
Vue自定义指令意外生效的解析及解决方案
本文分析一个Vue自定义指令校验问题:一个用于限制输入框只能输入数字的自定义指令,意外地影响了另一个未应用该指令的输入框。
我们定义了一个全局指令 validateNumber,用于校验输入框只能输入数字,并包含最小值和最大值限制:
Vue.directive('validateNumber', {
bind(el, binding, vnode) {
let lastData = null;
el.onkeyup = (e) => {
if (String.fromCharCode(e.keyCode) === 'E' || String.fromCharCode(e.keyCode) === 'KeyE') {
e.target.value = lastData;
return false;
} else {
lastData = e.target.value;
}
e.target.value = e.target.value.replace(/[^\d]/ig, '');
let _this = vnode.context;
_this.accessNestedObject(_this, vnode.data.model.expression, e.target.value);
if (binding.expression && e.target.value) {
let obj = (new Function("return " + binding.expression))();
let keys = Object.keys(obj);
let values = Object.values(obj);
if (keys[0] === 'min') {
if (parseInt(e.target.value) < parseInt(values[1])) {
e.target.value = values[1];
}
}
}
el.dispatchEvent(new Event('input'));
};
}
});
在模板中,我们仅将指令应用于第一个输入框:
秒 米
然而,第二个输入框也表现出只能输入数字的限制。这并非由于指令的错误应用,而是因为 el-input 本身 type="number" 属性的限制。 type="number" 属性在原生HTML中就限制了输入类型为数字。
立即学习“前端免费学习笔记(深入)”;
解决方案:
如果需要第二个输入框允许输入非数字字符,只需将 type="number" 改为 type="text":
米
这样,第二个输入框将不受 type="number" 的限制,而自定义指令 v-validateNumber 也不会对其产生影响,因为该指令只作用于应用了它的元素。 问题并非指令本身的错误,而是对HTML原生属性的误解导致的。










