在 textarea 上使用 v-model
优质
小牛编辑
131浏览
2023-12-01
会在 iOS 上出现 v-model 在 textarea 上不生效的问题,原因是在 iOS 真机上,无法动态在 textarea 设置 data-
,即:
<textarea data-cid="{{cid}}" bindinput="onInput"></textarea>
当 input
事件触发时,无法从事件对象上取得 dataCid
的值,从而无法根据上面的信息找到对于的事件处理方法。
解决方法
框架必须依赖于原生标签上 data-
的属性找到对于的事件处理方法,在实际测试中,除了原生小程序组件以外,自定组件也可以动态设置 data-
属性。所以可以利用自定义组件给 textarea
包裹的方式要绕开这个问题。
定义
定义自定义组件 textarea
,组件的代码:
index.wxml
<textarea
placeholder="{{placeholder}}"
placeholder-style="{{placeholderStyle}}"
placeholder-class="{{placeholderClass}}"
disabled="{{disabled}}"
auto-focus="{{autoFocus}}"
focus="{{focus}}"
auto-height="{{autoHeight}}"
fixed="{{fixed}}"
cursor-spacing="{{cursorSpacing}}"
cursor="{{cursor}}"
show-confirm-bar="{{showConfirmBar}}"
selection-start="{{selectionStart}}"
selection-end="{{selectionEnd}}"
adjust-position="{{adjustPosition}}"
maxlength="{{maxlength}}"
value="{{value}}"
bindinput="proxy"
bindblur="proxy"
bindfocus="proxy"
bindblur="proxy"
bindlinechange="proxy"
>
</textarea>
index.js
Component({
properties: {
placeholder: { type: String, value: '' },
placeholderStyle: { type: String, value: '' },
placeholderClass: { type: String, value: '' },
disabled: { type: Boolean, value: false },
autoFocus: { type: Boolean, value: false },
focus: { type: Boolean, value: false },
autoHeight: { type: Boolean, value: false },
fixed: { type: Boolean, value: false },
cursorSpacing: { type: Number | String, value: 0 },
cursor: { type: Number, value: 0 },
showConfirmBar: { type: Boolean, value: true },
selectionStart: { type: Number, value: -1 },
selectionEnd: { type: Number, value: -1 },
adjustPosition: { type: Boolean, value: true },
maxlength: { type: Number, value: 140 },
value: { type: String, value: '' }
},
methods: {
proxy(e) {
this.triggerEvent(e.type, e.detail);
}
}
});
index.wxss
textarea{
width:inherit;
height:inherit;
display:inherit;
position:inherit;
}
index.json
{
"component": true
}
使用
自定义组件配置:
index.js
export default {
config: {
usingComponents: {
textarea: 'path/to/components/textarea/index'
}
}
}
index.vue
<textarea v-model="input"></textarea>
使用就和正常的使用方式一样。原生自定义组件可以通过配置 webpack copy plugin 自动拷贝到指定目录,不需要额外的编译转换(除非你使用了可能在低版本系统中不支持的语法)。
这个方法不优雅,但能绕开这个问题。如果你有更优雅的解决思路,欢迎提 issue。
延伸
如果还碰到原生标签无法绑定事件的问题,大概率是类似的原因,即 data-
无法设置成功,可以尝试采用类似的解决方法。如果仍然无法解决,请提 issue。
相关 issue: