vue指令限制input输入金额 / 禁止粘贴
直接上代码:
export default {
inserted(el,vDir, vNode) {
// vDir.value 有指令的参数
let content ='';
let defaultPrecision =2;
let defaultMax =999999999.99; // 999999999.99
let defaultMin =0;
let $inp =findEle(el, 'input');
el.$inp = $inp;
//按键按下=>只允许输入 数字/小数点
el.addEventListener("keypress", event => {
let e = event || window.event;
let inputKey = String.fromCharCode(typeof e.charCode ==='number' ? e.charCode : e.keyCode);
let arg_precision =parseFloat(vDir.value && vDir.value.precision >=0 ? vDir.value.precision : defaultPrecision);
let re =/\d|\./;
content = e.target.value;
//定义方法,阻止输入
function preventInput(){
if (e.preventDefault) {
e.preventDefault();
}else {
e.returnValue =false;
}
}
if (!re.test(inputKey) && !e.ctrlKey) {
preventInput();
}else if ((content.indexOf(".") >0 && inputKey ==".") || (arg_precision ===0 && inputKey ==='.')) {
//已有小数点,再次输入小数点
preventInput();
}
});
//按键弹起=>并限制最大最小 "keydown" :防止长按数字键监听不到的情况
["keyup", "keydown", "focusout"].forEach(function(item,index){
el.addEventListener(item, event => {
let e = event || window.event;
let val = e.target.value;
val = val.replace(/[^\d.]/g, ""); //清除“数字”和“.”以外的字符
if(val ==='.'){
val ='';
}
if(val !== e.target.value){
vNode.componentInstance.$emit('input', val);
return;
}
content =parseFloat(val);
if (!content) {
return;
}
let arg_max =parseFloat(vDir.value && vDir.value.max ? vDir.value.max : defaultMax);
let arg_min =parseFloat(vDir.value && vDir.value.min ? vDir.value.min : defaultMin);
let arg_precision =parseFloat(vDir.value && vDir.value.precision >=0 ? vDir.value.precision : defaultPrecision);
let index = val.indexOf(".");
if(arg_max && content > arg_max){
val = val.substr(0, val.length-1);
}
if(arg_min && content < arg_min){
val = arg_min;
}
if(arg_precision >=0){// 处理精度
val = val.substr(0, index >=0 ? (index + arg_precision +1) : (val.length +1))
}
if(index === (val.length -1) && arg_precision ===0){// 当精度为0,且输入的最后一位为小数点
val = val.substr(0, index)
}
vNode.componentInstance.$emit('input', val)
});
})
},
}
最重要的就是 vNode.componentInstance.$emit('input', val) 这一行代码,因为v-model指令其实就是input输入框双向绑定的语法糖,所以实时更新的时候需要在指令里手动触发input事件。
禁止粘贴:
export default {
inserted(el,vDir, vNode) {
//按键弹起
["paste"].forEach(function(item,index){
el.addEventListener(item, event => {
let e = event || window.event;
if (e.preventDefault) {
e.preventDefault();
}else {
e.returnValue =false;
}
});
})
},
}