VUE中实现输入框Input输入限制

在开发过程当中,基本都遇到过须要限制输入的状况,好比金额、仅字母数字、可输入小数位等,网上搜了不少方法也遇到一些坑,因此分享出来。css

1.使用修饰符实现数字输入

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

2.监听输入框变化

经过@input监听更新数据,实现只能输入数字,并且能够自行定制限制输入内容浏览器

<input v-model="testValue" @input="testValue = testValue.replace(/[^\d]/g,'')">

此方法能够知足需求,可是没法封装进行批量使用app

3.封装全局指令

封装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

好比输入abc123abc输入框内是 123,但实际testValue值是c123c

缘由是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'))
  }))
}

···

到这里算是知足了要求,也能方便的使用,分享出来但愿可以抛砖引玉,学习到更好的方式,若是有更好的方法请告诉我,谢谢!

相关文章
相关标签/搜索