原生input 输入框
<input type="text" v-moneynative="{num:4,couldNegative:true}" v-model="test">
新建一个vue.directive
该指令限制输入框只能有指定位数的数字
input + blur
实时输入实时验证改变值
// 这个也有缺陷
const moneynative = Vue.directive("moneynative",{
bind(el, binding) {
var defaultVal = {
num:2, //Number小数点位数
couldNegative:false, //负数?
}
let num = Object.assign(defaultVal,binding.value).num
let couldNegative = Object.assign(defaultVal,binding.value).couldNegative
el.handler = (e) => {
if(!e.target.value)return
let miusFont = (couldNegative && e.target.value.slice(0,1)== '-')?'-':''
let valueMiddle = e.target.value
valueMiddle = valueMiddle.toString().replace(/[^\d\.]/g, ''); //如果输入非数字,则替换为''
//必须保证第一个为数字而不是.
valueMiddle = valueMiddle.toString().replace(/^\./g,'');
//前两位不能是0加数字
valueMiddle = valueMiddle.toString().replace(/^0\d[0-9]*/g,'');
//保证只有出现一个.而没有多个.
valueMiddle = valueMiddle.toString().replace(/\.{2,}/g,'.');
//保证.只出现一次,而不能出现两次以上
valueMiddle = valueMiddle.toString().replace('.','$#$').replace(/\./g,'').replace('$#$','.');
//只能输入两位小数 或者多位
let str = Array.from({length:num}).reduce((total,item)=>{
return total+='\\d'
},'')
let part = `/^(\\-)*(\\d+)\\.(${str}).*$/`
valueMiddle = valueMiddle.toString().replace(eval(part),'$1$2.$3');
e.target.value = miusFont+valueMiddle
}
el.addEventListener("input", el.handler)
el.addEventListener("blur", el.handler)
},
unbind(el) {
el.removeEventListener('input', el.handler);
el.removeEventListener("blur", el.handler)
},
})
在输入超出位数的时候
image.png
value
虽然被改变了,但是 相应的 v-model
老是多一位。及时加了blur多触发一次也不行
修改 change + blur + 额外触发input
不能实施触发了
el.dispatchEvent(new Event('input'));
e.target.value = miusFont+valueMiddle
el.dispatchEvent(new Event('input'));
}
el.addEventListener("change", el.handler)
el.addEventListener("blur", el.handler)
},
unbind(el) {
el.removeEventListener('change', el.handler);
el.removeEventListener("blur", el.handler)
},
可以实现需求
原理是根据v-model
也是@input 完成和value的双向绑定
<input v-model="name" type="text"/>
<input :value="name" @input="name = $event.target.value" type="text"/>
但是在el-element el-input 也有效
网友评论