近期一直再忙于vue.js的项目开发,尤其是表单功能;今晚想抽出一个小技术点来说说。比如:输入姓名的表单验证系列问题。
对于姓名的验证,我们会想到几点:
1、用户只能输入中文
2、如果用户输入了非中文如何处理
3、用户从表单外复制非中文进来如何处理
4、限制输入的字数
接下来我们以一个实例来说明下,如何去寻找解决方法,
输入姓名的表单验证系列问题
这是一个存款案例,用银行转账的时候要求把中文姓名提交给后台去,然后把姓名的参数给第三方业务接口用。我自己做了2个方案:
方案一
HTML代码:
<Input v-model="name" placeholder="请输入真实姓名(中文)" style="width:auto;" clearable @keyup.native="inputChange($event)" @keydown.native="inputChange($event)"/>
html这里不多说,很简单的,我们主要介绍下JS如何操作。
inputChange(e) {
const o = e.target;
o.value = o.value.replace(/[^\u4E00-\u9FA5]/g, ''); // 清除除了中文以外的输入的字符
this.name = o.value;
},
上述的方法,看上去没什么问题的,我们定义点击、松开的两个状态,然后对于input绑定v-model的name值进行正则中文处理。不知道大家想到问题没?
其实这种方法,对于PC是可以的,如果对于移动端,大家可以去试试,发现问题就来了,点击可能出现无反应,尤其是对于ios这种比较挑的系统,各种BUG都来了。
总结下缺点:
keyup动作时验证:移动端兼容性不好
clipboard粘贴时验证:浏览器安全策略限制读取设备粘贴板,功能有限。
input动作时验证:不兼容IE,需要浏览器查询。对组件不友好,未达到需求效果。
方案二
那么我们如何去优化呢?让它也可以适用于移动端,于是寻找了另外的方法,进行优化,废话不多说,上代码:
HTML代码:
<!-- chinese name -->
<div class="pay-chinesename" v-if="showChineseName">
<input type="text" class="chinaName" placeholder="请填写真实姓名(中文)" @focus="checkStart" @blur="checkEnd" v-model="chineseName" name="chineseName" />
</div>
大家发现我们这里,把点击和松开的状态换成了focus和blur,其他的基本一样。当然JS做了不一样的处理。
// chinsename check
checkChinese(){
this.chineseName=this.chineseName.replace(/[^\u4E00-\u9FA5]/g, '')
},
checkStart(){
this.checkInterval=setInterval(this.checkChinese,100)
},
checkEnd(){
clearInterval(this.checkInterval)
console.log('chineseName:'+this.chineseName);
}
checkStart和checkEnd分别定义输入和离开时的状态的方法。
主要逻辑:
获取焦点时设置定时器,开始轮询验证,失去焦点后清除定时器。
设置的是0.1秒验证一次,每次验证将输入框内容不符合正则的字符去除。验证间隔可以自己设置更短。获取焦点时开始验证,失去焦点后停止验证。
看上去是不是感觉思维更加缜密了,当然看归看,我们得去试下才行,这里就不弄DEMO了。
总结下优点:
此方法有着极高的兼容性,通用性,textarea也适用。
适用事件为经典事件,几乎所有框架,相关组件都可以使用,基本能兼容各种浏览器,设备。
差点遗漏了一点,限制输入文字的长度,我觉得这个非常简单,用length方法即可。
OK,已经有点晚了,就说这么多吧,最后简单总结下吧。
总结
上面列举的两种方案,第一种是我最开始使用的,第二种方案是从网上搜集到的,说实话,有时候只有对比才有"伤害",跟我们平时购物一样,你没用过,你根本不知道优劣之分。
话说回来,表单验证方法还有很多,比如插件和框架提供的方法等等,如果更好的方法都可以分享出来,留言或者QQ,不吝赐教。