[BUG记录] element-ui / element-plus 的 Select 可搜索组件在 iOS 下无法唤起软键盘

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

项目场景

运行环境vue@3.2.37, element-plus@2.2.9


问题描述

element-plus 的 Select 组件可以通过 filterable 属性开启搜索功能该组件在iOS系统中点击组件输入框无法唤起软键盘。


原因分析

此bug自 element-ui 就有了是该组件内部输入框的 readonly 属性导致的问题。


解决方案

1. element-ui

这个bug element-ui 和 element-plus 都有可以参考这篇文章ElementUI的Select组件在IOS唤不起软键盘解决
注意此方案在 element-plus 下有bug首次点击仍然概率无法唤起软键盘。

<el-select 
  v-model="value"
  placeholder="Select"
  ref="select"
  @hook:mounted="cancalReadOnly(false, 'select')"
  @visible-change="(value) => cancalReadOnly(value, 'select')"
>
  <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
cancalReadOnly(value, refTxt) {
  this.$nextTick(() => {
    if(!value) {
      this.$refs[refTxt]?.$el?.querySelector('.el-input__inner')?.removeAttribute('readonly')
    }
  })
},

此方案总结一下就是在Select组件 mounted 以及 Select下拉框隐藏时移除Select组件内部输入框的readonly属性。

分别避免首次、后续点击输入框时无法唤起软键盘。

2. element-plus

element-plus 下未能解决的原因在于vue3中去除了这个钩子 hook:mounted (参考Vue官方文档里没告诉你的神秘钩子——@hook)。

hook:mounted 绑定了Select组件的mounted方法。

前面也总结过vue3.x下此钩子的失效导致了无法避免首次点击产生的bug。那么能否使用其它钩子或者DOM原生事件取代它呢

element-plus 解决方案

Select组件并不支持其它的DOM原生事件但它提供了插槽。可以通过监听插槽内元素的加载或者直接插入一个测试元素在Select组件内间接监听Select组件是否加载完毕。

示例
由于图片元素支持onload事件在Select组件内添加一张图片。需添加样式隐藏该图片图片内容无用所以大小应尽量小。

<el-select 
  v-model="value"
  placeholder="Select"
  ref="select"
  @visible-change="(value) => cancalReadOnly(value, 'select')"
>
  <img style="display:none" @load="cancalReadOnly(false, 'select')" src="@/assets/images/ios-keyboard-bug.png" />
  <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>

也可将图片放在Select插槽内不过插槽有边距等样式问题


其它未验证方案

vue3.0 项目中 el-select ios 无法唤起软键盘解决
ElementUI的Select组件在IOS唤不起软键盘

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6