基于vue注册自定义指令限制输入框输入中文/数字/英文/数字保留N位小数

431 阅读1分钟

1.写入指令内容

创建一个limitInput.js文件写入代码,具体开发内容在代码内注释标明,时间有限暂时未做火狐兼容版本

export default {
  /* 兼容性检测
    chrome:oncompositionstart--->oninput--->oncompositionend
    firefox: oncompositionstart--->oncompositionend--->oninput */
  /* 限制输入中文+空格/英文+空格/数字+空格/保留 binding.value 位小数 */
  bind(el, binding) {
    const arg = binding.arg
    // 限制规则
    const restrictRule = {
      zh: /[^\s\u4E00-\u9FA5\s]/g, // 中文
      en: /[^a-zA-Z\s]/g, // 英文
      number: /[^0-9]/g, // 纯数字
      float: (val) => {
        // 保留 v-limitInput:float="n" n位小数数字
        val =
          val.indexOf('.') > -1
            ? val.slice(0, val.indexOf('.') + binding.value + 1)
            : val
        return val.replace(/[^0-9\.]/g, '')
      }
    }
    const multiValitor = ['float'] // 多重限制类型
    const restrict = restrictRule[binding.arg]
    let inputLock = false // 输入锁 使用输入法时关闭限制 结束输入法输入时触发限制
    const doRule = (e) => {
      // 判断是否多重校验形式
      if (multiValitor.indexOf(arg) === -1) {
        e.target.value = e.target.value.replace(restrict, '')
      } else {
        e.target.value = restrictRule[arg](e.target.value)
      }
      // 手动更新绑定值
      e.target.dispatchEvent(new Event('input'))
    }
    const target =
      el instanceof HTMLInputElement ? el : el.querySelector('input')
    target.addEventListener('input', (event) => {
      /* 
        若不是手动输入(inputType === 'insertText'),是更新时触发此事件则不再执行校验
        防 dispatchEvent 无限触发限制校验
      */
      if (!inputLock && event.inputType === 'insertText') {
        doRule(event)
        event.returnValue = false
      }
      event.returnValue = false
    })
    /* 使用输入法开始触发 */
    target.addEventListener('compositionstart', (event) => {
      inputLock = true
    })
    /* 结束输入法使用触发 */
    target.addEventListener('compositionend', (event) => {
      inputLock = false
      doRule(event)
    })
  }
}

2.在Vue中注册指令

创建一个index.js文件写入注册指令的内容路径自行调整

import limitInput from './input/limitInput'

const install = function (Vue) {
  Vue.directive('limitInput', limitInput) // 限制输入 (中文/英文/数字/小数+N位数)
}

export default install

3.在main.js中引入

// '.directive/index.js'
import directive from './directive' // directive 引入注册指令的文件安装指令 路径已忽略index.js

Vue.use(directive)