vue自定义指令——input输入类型限制(数字、浮点、整数、英文等),解决中文输入法双向绑定失效问题


版本更新

2023.3.23——修复浮点型输入0问题

前言

实现一个vue自定义指令——输入框(input,el-input)输入内容类型限制,解决中文输入法双向绑定失效问题,多种类型支持,数字类型,浮点类型、英文类型、整数类型、四则运算等


一、基本步骤

以element,el-input组件为例:
1.在自定义指钩子函数bind或inserted通过querySelector找到输入框(input标签)dom对象
2.监听input的onkeyup事件,获取输入值,校验并替换输入值,限制输入类型,重新给输入框设值
3.通过compositionstart和compositionend事件设置锁定标识,解决中文输入法双向绑定失效问题

二、代码实现

1.input.js

代码如下:

export default {
    
    
  bind(el, binding, vnode) {
    
    
    const input = el.querySelector('.el-input__inner') || el.querySelector('.el-textarea__inner') || el;
    input.addEventListener('compositionstart', () => {
    
    
      vnode.locking = true//解决中文输入双向绑定失效
    })
    input.addEventListener('compositionend', () => {
    
    
      vnode.locking = false//解决中文输入双向绑定失效
      input.dispatchEvent(new Event('input'))
    })
    //输入监听处理
    input.onkeyup = () => {
    
    
      if (vnode.locking) {
    
    
        return;
      }
      // v-input.num
      if (binding.modifiers.num) {
    
    //只能输入数字(开头可以多个0)
        onlyNum(input);

      }
      //v-input.num_point
      else if (binding.modifiers.num_point) {
    
    //只能输入数字+小数点(可以多个小数点)
        onlyNumPoint(input)
      }
      //v-input.float
      else if (binding.modifiers.float) {
    
    //只能输入浮点型(只能一个小数点)
        onlyFloat(input, binding.value)
      }
      //  v-input.int
      else if (binding.modifiers.int) {
    
    //只能输入整数(0+正整数)(开头不能多个0)
        onlyInt(input)
      }
      //v-input.intp
      else if (binding.modifiers.intp) {
    
    //只能输入正整数
        onlyIntp(input)
      }
      //v-input.alp
      else if (binding.modifiers.alp) {
    
    //只能输入字母
        onlyAlp(input)
      }
      //v-input.num_alp
      else if (binding.modifiers.num_alp) {
    
    //只能输入数字+字母
        onlyNumAlp(input)
      }
      //v-input.arith
      else if (binding.modifiers.arith) {
    
    //四则运算符+数字
        onlyArith(input)
      }
      input.dispatchEvent(new Event("input"));
    }

    //数字
    function onlyNum(input) {
    
    
      input.value = input.value.replace(/\D+/g, '');
    }
    //整数(0+正整数)
    function onlyInt(input) {
    
    
      let value = input.value;
      value = value.replace(/\D+/g, '');
      input.value = value ? Number(value).toString() : value//去掉开头多个0
    }
    //正整数
    function onlyIntp(input) {
    
    
      if (!/^[1-9][0-9]*$/.test(input.value)) {
    
    
        let value = input.value.replace(/\D+/g, '');
        if (value && value.substring(0, 1) === '0') {
    
    //0开头去除0
          value = value.substring(1)
        }

        input.value = value
      }
    }

    //数字+小数点
    function onlyNumPoint(input) {
    
    
      input.value = input.value.replace(/[^\d.]/g, "");
    }

    //浮点型
    // eslint-disable-next-line no-unused-vars
    function onlyFloat(input, n) {
    
    
      let value = input.value;
      value = value.replace(/[^\d.]/g, '');
      value = value.replace(/^\./g, '');
      value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
      if (n&&Number(n)>0) {
    
    //限制n位
        var d = new Array(Number(n)).fill(`\\d`).join('');
        // eslint-disable-next-line no-useless-escape
        var reg = new RegExp(`^(\\-)*(\\d+)\\.(${
    
    d}).*$`, 'ig');
        value = value.replace(reg, '$1$2.$3')
      }
      if (value && !value.includes('.')) {
    
    
           value =  Number(value).toString()//去掉开头多个0
      }
      input.value = value
    }
    //字母
    function onlyAlp(input) {
    
    
      input.value = input.value.replace(/[^A-Za-z]/g, '');
    }
    //数字+字母
    function onlyNumAlp(input) {
    
    
      input.value = input.value.replace(/[^A-Za-z0-9]/g, '');
    }

    //四则运算+-*/()数字
    function onlyArith(input) {
    
    
      let value = input.value
      if (value) {
    
    
        input.value = value.split('').reduce((prev, cur) => {
    
    
          // eslint-disable-next-line no-useless-escape
          if (/^[\d|\-|\+|\*|\/|\.|\(|\)]+$/.test(cur)) {
    
    
            return prev + cur
          }
          return prev
        }, '')
      }
    }

  },

}






2.install.js(注册文件)

代码如下:

import input from "./input.js";

export default{
    
    
    install:Vue=>{
    
    
        Vue.directive('input',input)
    }
}

3.全局注册

main.js

 import inputDirective from './directive/input/install';
 Vue.use( inputDirective );

4.页面调用

         <!-- 只能数字 -->
        <el-input v-input.num v-model="input"></el-input>
         <!-- 只能数字+小数点 -->
        <el-input v-input.num_point v-model="input"></el-input>
         <!-- 只能整数 -->
        <el-input v-input.int v-model="input"></el-input>
         <!-- 浮点型后面限制2-->
        <el-input v-input.float="2" v-model="input"></el-input>
         <!-- 只能英文 -->
        <el-input v-input.alp v-model="input"></el-input>

三、使用说明

指令 说明
v-input.num 只能输入数字(开头可以多个零)
v-input.num_point 只能输入数字+小数点(可以多个小数点,开头可以多个零)
v-input.int 只能输入整数(0+正整数)(开头不能多个0)
v-input.intp 只能输入正整数
v-input.float 只能输入浮点型 n:限制输入小数点后n位,默认不限制
v-input.alp 只能输入字母
v-input.num_alp 只能输入数字+字母
v-input.arith 四则运算符+数字

可以按需在扩展类型限制指令

四、npm安装指令插件

npm install vue-el-input-directive

main.js

import  inputDirective from 'vue-el-input-directive'
Vue.use(inputDirective)

猜你喜欢

转载自blog.csdn.net/sd1sd2/article/details/127818207
今日推荐