什么是输入验证限制
vue输入验证限制,即在输入框输入的过程中,对字符进行限制,去除不符合要求的字符,保留我们想要的数据。这是我们经常遇到的需求,也是辅助表单验证的一种方式。
为何说是辅助表单验证的一种方式?
假设表单的某个输入框,我们只允许输入数字,那么做了输入限制后,那么表单验证,我们就只需做必填验证就可以了。
接下来,让我们通过几个示例,逐步了解输入验证:
vue输入验证限制 - 正整数限制
准备前置资源
- vue.js
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script> - Dom结构
... <body> <div id="app"> <input ref="text" :value="text" @input="inputChange" placeholder="正整数"></input> {{text}} </div> </body> - js
new Vue({ el: '#app', data: function() { return { text: '' } }, methods: { inputChange(e) { this.text = e.target.value; } } })
验证输入数据
接下来改造 inputChange方法:
...,
methods: {
inputChange(e) {
let reg = /^[0-9]*$/;
if (reg.test(e.target.value)) {
// 只有输入数字时才会同步数据
this.text = e.target.value;
}
}
},
...
方法改造后,我们会发现,输入数字时才会将数据同步到 text, 但是input输入框内数据与 text数据并未保持一致;

那出现这种UI没有更新的情况,我们怎么办呢?
-
手动更新
手动更新,即直接操作DOM改变input的数据
..., inputChange(e) { let reg = /^[0-9]*$/; if (reg.test(e.target.value)) { // 只有输入数字时才会同步数据 this.text = e.target.value; return; } console.log('UI value - before: ', e.target.value); // 更新DOM数据 // this.$refs.text.value = this.text; e.target.value = this.text; console.log('UI value - after: ', e.target.value); } ...

-
制造UI更新的条件
根据Vue的更新机制,我们知道当数据产生 变动 时,就会触发UI的更新,那么我们可以这么做:
..., inputChange(e) { let reg = /^[0-9]*$/; if (reg.test(e.target.value)) { // 只有输入数字时才会同步数据 this.text = e.target.value; return; } console.log('dom update before = ', e.target.value); // 制造数据变动,触发更新机制 this.text += '$'; // this.text += ' '; console.log('add $ = ', this.text); // await this.$nextTick(); // this.text = this.text.trim(); this.text = String(this.text).substring(0, this.text.length - 1); console.log('remove $ = ', this.text); this.$nextTick( () => { console.log('dom update after = ', e.target.value); }); } ...
数据粘贴问题
做完了以上操作后,我们已经可以保证,输入的时候只能输入整数了。
但是如果我们复制一段包含文字、数字及其它字符到上面的输入框时,你会发现我们无法粘贴到里面,那么如果我们想在粘贴时,提取数字到输入框中改怎么做呢?
我们换种数据赋值的方式:
...,
inputChange(e) {
// 根据正则替换掉 0-9以外的数据
this.text = e.target.value.replace(/[^0-9]/g,'');
// 更新UI
e.target.value = this.text;
}
...
修改之后就可以达到我们想要的效果,不过如果没有特别的要求,大可不必使用这种方式。

输入中文的问题
当我们用输入法输入中文时,你会发现,输入框会先在输入框中添加占位,然后再将占位替换为对应的中文,而在以上的数据框中,输入中文,我们会发现,占位符被替换掉了,导致我们非预期的结果。
出现这种情况,主要是因为,我们在输入中文的过程中,input方法仍然会触发,导致占位符被替换掉导致的。
为了解决这种问题,我们可以使用两种方法解决:
-
手动绑定 compositionstart、compositionend方法
compositionstart 可以监听我们是否在输入中文 compositionend 可以监听输入的中文是否进入了输入框, 而input方法的触发时机,正好在这两个方法中间,那么:
<div id="app"> <input ref="text" :value="text" @input="inputChange" placeholder="正整数" @compositionstart="onCompositionStart" @compositionend="onCompositionEnd" ></input> {{text}} </div>..., methods: { ..., onCompositionStart(e) { e.target.composing = true; }, onCompositionEnd(e) { if (!e.target.composing) { return } e.target.composing = false; // 输入中文完成后, 数据处理 this.inputChange(e); }, inputChange(e) { if (e.target.composing) { // 输入中文过程不做数据处理 return; } // 根据正则替换掉 0-9以外的数据 this.text = e.target.value.replace(/[^0-9]/g,''); // 更新UI e.target.value = this.text; } ... }, ...
-
用 v-model 进行数据绑定
其实我们我们没有必要自己绑定 compositionstart、compositionend 方法,当我们使用 v-model进行双向绑定时,vue已为我们绑定了对应事件,详情请看 vue文档 。
...
<input ref="text" v-model="textCpu" placeholder="v-model"></input>
...
...,
computed: {
textCpu: {
get() {
return this.text;
},
set(val) {
this.text = val.replace(/[^0-9]/g,'');
this.$refs.text.value = this.text;
}
}
},
...
这样我们就可以直接省略第一种方法的步骤了,当然实现原理是我们需要了解掌握的。
vue输入验证限制 - 浮点数限制
有了上面的经验,那我们尝试实现一个只能输入浮点数输入框。
...
<input ref="num" v-model="text2Cpu" placeholder="输入小数"></input>
...
// 提取字符串中符合符合浮点数的数据
function getFloatStr(str = '', digit = 2) {
// 是否已经出现了小数点
var hasPoint = false;
// 去除 数字 和 . 之外的字符
str = str.replace(/[^0-9\.]/g, '');
str = str.replace(/\.*/g, function(v) {
if (v) {
// 第一次出现的 1 到多个小数点 保留/替换为一个
if (!hasPoint) {
// 第一次出现的 1 到多个小数点 保留/替换为一个
hasPoint = true;
return '.';
}
// 去掉其它小数点
return '';
}
// 去掉其它小数点
return v;
});
// var reg = new RegExp(`^\\d+\\.?\\d{0,${digit}}`);
var reg = new RegExp('^\\d+\\.?\\d{0,'+ digit +'}');
let m = str.match(reg);
// console.log(m, '--');
return !!m ? m[0] : '';
// let r = parseFloat(str);
// return r ? r.toFixed(digit) : '';
}
...,
data: function() {
return {
text: '',
num: ''
}
},
computed: {
...
text2Cpu: {
get() {
return this.num;
},
set(val) {
console.log('data before: ', val);
this.num = getFloatStr(val, 2);
this.$refs.num.value = this.num;
console.log('data after: ', this.num);
}
}
},
...

至此我们就完成了,输入框输入保留2位小数的输入限制操作。
总结
根据上面的示例,我们可以看出,输入验证对我们的考验有两个:
- 保持绑定数据与UI的同步。
- 熟练使用正则进行数据匹配、替换等。
基于以上,我想我们可以做更多类似的事情,如:
- 只允许输入英文
- 只允许输入16进制字符
- 只允许输入中文
- 不允许输入空格
- 不允许输入特殊字符
- 控制输入数字最小值
- 控制输入数字最大值
- 控制输入长度
...
必要的时候,我们可以封装成组件,便于使用。
至此,希望可以为大家提供举一反三的灵感,解决更多的问题。