在开发过程当中,基本都遇到过须要限制输入的状况,好比金额、仅字母数字、可输入小数位等,网上搜了不少方法也遇到一些坑,因此分享出来。css
在VUE
中能够在v-modal
后添加修饰符的形式来限制输入,好比:html
<input v-model.number="testValue" type="number">
.number
能够实现限制数字输入,可是会有如下问题:vue
type="number"
自带样式,固然能够经过添加如下css清除/* 普通IE浏览器 样式清除 */ input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{ -webkit-appearance: none !important; } /* 火狐浏览器样式清除 */ input[type="number"]{ -moz-appearance:textfield; }
+-.
,会致使清空data中的值testValue
这里的修饰符也没法实现定制限制输入,不能知足要求web
经过@input
监听更新数据,实现只能输入数字,并且能够自行定制限制输入内容浏览器
<input v-model="testValue" @input="testValue = testValue.replace(/[^\d]/g,'')">
此方法能够知足需求,可是没法封装进行批量使用app
封装input限制输入指令ide
//input.js const addListener = function(el, type, fn) { el.addEventListener(type, fn, false) } //去掉空格 const spaceFilter = function(el) { addListener(el, 'input', () => { el.value = el.value.replace(/\s+/, '') }) } // 限制只能输入整数和小数(价格类、最多两位小数) const priceFilter = function(el) { addListener(el, 'input', () => { el.value = (el.value.match(/^\d*(\.?\d{0,2})/g)[0]) || null if (isNaN(el.value)) { el.value = '' } }) } export default { bind(el, binding) { if (el.tagName.toLowerCase() !== 'input') { el = el.getElementsByTagName('input')[0] } spaceFilter(el) switch (binding.arg) { case 'price': priceFilter(el) break default: console.warn('未知指令类型',binding.arg) break } } }
注册全局自定义指令学习
//main.js import inputFilter from '@/directives/InputFilter.js' Vue.directive('inputFilter', inputFilter)
使用v-input-filter
指令ui
<input v-modal="testValue" v-input-filter:price>
这样封装在使用时会出现一个隐蔽的bug,就是在输入指令中正则限制之外的字符时,视图中输入框显示是正确的,可是在浏览器控制栏Vue Devtools
中的testValue
最后一位字符是最后输入的时的字符。this
好比输入abc
、123abc
输入框内是
、123
,但实际testValue
值是c
、123c
。
缘由是vue中绑定的值是经过监听input进行赋值的,直接修改输入框值不会触发input
事件,须要经过dispatchEvent
再次手动触发input
事件,修改以下:
//input.js ··· // 防抖 let debounce = (fn, delay) => { var delay = delay || 100; var timer; return function() { var th = this; var args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(function() { timer = null; fn.apply(th, args); }, delay); }; } ··· // 限制只能输入整数和小数(价格类、两位小数) const priceFilter = function(el) { addListener(el, 'input', debounce(() => {//添加防抖 防止反复触发事件致使内存溢出 el.value = (el.value.match(/^\d*(\.?\d{0,2})/g)[0]) || null if (isNaN(el.value)) { el.value = '' } //触发input事件 el.dispatchEvent(new Event('input')) })) } ···
到这里算是知足了要求,也能方便的使用,分享出来但愿可以抛砖引玉,学习到更好的方式,若是有更好的方法请告诉我,谢谢!