監(jiān)聽輸入框變化
通過@input
監(jiān)聽更新數(shù)據(jù)铺浇,實(shí)現(xiàn)只能輸入數(shù)字挺狰,而且可以自行定制限制輸入內(nèi)容
<input v-model="testValue" @input="testValue = testValue.replace(/[^\d]/g,'')">
此方法可以滿足需求驻仅,但是無法封裝進(jìn)行批量使用
封裝全局指令
封裝input
限制輸入指令,限制只能輸入整數(shù)和小數(shù)
//index.js
const addListener = function (el, type, fn) {
el.addEventListener(type, fn, false)
}
let enterNumber = {
bind: function (el, binding) {
if (el.tagName.toLowerCase() !== 'input') {
el = el.getElementsByTagName('input')[0]
}
let val = binding.value === undefined ? 2 : binding.value;
if (val !== 0) {
val += 1;
}
addListener(el, 'input', () => {
el.value = (el.value).replace(/[^\d.]/g, '').replace(/^\./g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
// 清除'數(shù)字和'.'以外的字符
//el.value = el.value.replace(/[^\d.]/g, '');
// 必須保證第一個為數(shù)字而不是'.'
//el.value = el.value.replace(/^\./g, '');
// 保證只有出現(xiàn)一個'.'而沒有多個'.'
//el.value = el.value.replace(/\.{2,}/g, '.');
//el.value = el.value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
if ((el.value).indexOf('.') !== -1) {
el.value = el.value.substring(0, (el.value).indexOf('.') + val)//保留幾位小數(shù)
}
})
}
}
export default {
enterNumber,
}
注冊全局自定義指令
//main.js
import myDirective from './myDirective/index'
Object.keys(myDirective).forEach(item => {
Vue.directive(item, myDirective[item])
})
使用指令
<el-input v-model="num" placeholder="輸入數(shù)字" v-enter-number='2'></el-input>
這樣封裝在使用時會出現(xiàn)一個隱蔽的bug
挽牢,就是在輸入指令中正則限制以外的字符時与学,視圖中輸入框顯示是正確的彤悔,但是在瀏覽器控制欄Vue Devtools
中的num
最后一位字符是最后輸入的時的字符。
比如輸入abc索守、123abc
輸入框內(nèi)是 蜗巧、123,但實(shí)際num
值是c蕾盯、123c
幕屹。
原因是vue
中綁定的值是通過監(jiān)聽input
進(jìn)行賦值的,直接修改輸入框值不會觸發(fā)input
事件级遭,需要通過dispatchEvent
再次手動觸發(fā)input
事件望拖,但是在監(jiān)聽的input
回調(diào)中再觸發(fā)input
會無限循環(huán),所以調(diào)整為監(jiān)聽keyup
事件來修改值挫鸽,修改如下:
const addListener = function (el, type, fn) {
el.addEventListener(type, fn, false)
}
let enterNumber = {
bind: function (el, binding) {
if (el.tagName.toLowerCase() !== 'input') {
el = el.getElementsByTagName('input')[0]
}
let val = binding.value === undefined ? 2 : binding.value;
if (val !== 0) {
val += 1;
}
addListener(el, 'keyup', () => {
el.value = (el.value).replace(/[^\d.]/g, '').replace(/^\./g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
// 清除'數(shù)字和'.'以外的字符
//el.value = el.value.replace(/[^\d.]/g, '');
// 必須保證第一個為數(shù)字而不是'.'
//el.value = el.value.replace(/^\./g, '');
// 保證只有出現(xiàn)一個'.'而沒有多個'.'
//el.value = el.value.replace(/\.{2,}/g, '.');
//el.value = el.value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
if ((el.value).indexOf('.') !== -1) {
el.value = el.value.substring(0, (el.value).indexOf('.') + val)//保留幾位小數(shù)
}
el.dispatchEvent(new Event('input'))
//通過dispatchEvent再次手動觸發(fā)input事件
})
}
}
export default {
enterNumber,
}
到這里算是滿足了要求说敏,也能方便的使用,分享出來希望能夠拋磚引玉丢郊,學(xué)習(xí)到更好的方式盔沫,如果有更好的方法請告訴我,謝謝枫匾!