new Vue({
el: '#app',
data() {
return {
dataInt: 0,
dataFloat: 0
}
},
directives: {
inputInt: {
bind(el, binding, vnode) {
let input = vnode.elm;
input.addEventListener('compositionstart', () => {
vnode.inputLocking = true
})
input.addEventListener('compositionend', () => {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', () => {
if(vnode.inputLocking) {
return;
}
let oldValue = input.value;
let newValue = input.value.replace(/[^\d]/g, '');
if(newValue && binding.value !== 'zeroBefore') {
newValue = newValue.replace(/^\b(0+)/gi, '') // 不指定可以以0开头的时候 去掉开头多余的0
}
// 判断是否需要更新,避免进入死循环
if(newValue !== oldValue) {
input.value = newValue
// 通知v-model更新 vue底层双向绑定实现的原理是基于监听input事件
input.dispatchEvent(new Event('input'))
}
})
}
},
inputFloat: {
bind(el, binding, vnode) {
let input = vnode.elm;
input.addEventListener('compositionstart', () => {
vnode.inputLocking = true
})
input.addEventListener('compositionend', () => {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', () => {
if(vnode.inputLocking) {
return;
}
let oldValue = input.value;
let newValue = input.value;
newValue = newValue.replace(/[^\d.]/g, '');
newValue = newValue.replace(/^\./g, '');
newValue = newValue.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
newValue = newValue.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
if(newValue) {
let arr = newValue.split('.')
newValue = Number(arr[0]) + (arr[1] === undefined ? '' : '.' + arr[1]) // 去掉开头多余的0
}
// 判断是否需要更新,避免进入死循环
if(newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
// input 事件无法处理小数点后面全是零的情况 因为无法确定用户输入的0是否真的应该清除,如3.02。放在blur中去处理
input.addEventListener('blur', () => {
let oldValue = input.value;
let newValue = input.value;
if(newValue) {
newValue = Number(newValue).toString()
}
// 判断是否需要更新,避免进入死循环
if(newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
}
}
}
})
网友评论