背景:需求要求密码输入框不能输入空格,于是找到easyinput的 trim API,但是通过测试,发现去除空格的方法时不时“失效”,哪怕使用 trim="all"
,依旧会存在最后面的空格在输入框没有自动删除的情况。然而通过打印绑定值发现,绑定值生效,并没有空格,但没有更新到输入框。
通过查看easyinput的代码和生效过程,发现是原生input赋值没有及时生效的缘故,因此我们修改下源代码:
在ui-modules中找到uni-easyinput.vue,修改onInput
方法:
给赋值的val增加this.$nextTick()
onInput(event) {
let value = event.detail.value;
// 判断是否去除空格
if (this.trim) {
if (typeof(this.trim) === 'boolean' && this.trim) {
value = this.trimStr(value)
}
if (typeof(this.trim) === 'string') {
value = this.trimStr(value, this.trim)
}
};
if (this.errMsg) this.errMsg = ''
// 修改===输入空格在输入框没有渲染问题
this.val = null
this.$nextTick(function() {
this.val = value
})
// TODO 兼容 vue2
this.$emit('input', value);
// TODO 兼容 vue3
this.$emit('update:modelValue', value)
},
到这里,就已经解决了trim
没有渲染的问题。
期间,需求增加验证码输入框不能输入非数字的字符验证,在@input方法内再增加this.$nextTick()
就可:
inputChange(value) {
let that = this
this.$nextTick(() => {
that.formData.authCode = value.replace(/\D+/g, '')
})
}
其后,需求又增加了密码框不能输入中文校验,这时用上面的this.$nextTick
竟然没有生效,打断点发现,是我们逻辑的this.$nextTick
走在了我们第一步给原生赋值的前面,使没有渲染上,因此采用setTimeout
,生效。如下:
pwdInput(val) {
setTimeout(() => {
let pwd = val.replace(/[\u4e00-\u9fa5]/g, '')
this.$set(this.formData, 'loginPwd', pwd)
}, 100)
}
因此,综上场景和测试,使绑定数据正则之后在逻辑层和渲染层都生效的方法是:
- 如第一步,修改easyinput赋值方法
- 同第三步,在逻辑层用setTimeout,保证赋值之后的渲染
上面的第二个方法,有一定随机性,还是拥抱setTimeout吧!~