美文网首页
【directives】自定义指令之input数值

【directives】自定义指令之input数值

作者: 两年半练习程序员 | 来源:发表于2022-06-24 14:05 被阅读0次

    需求

    由于input输入框的number类型不调好用,故通过自定义指令给element el-input组件设置输入限制

    功能

    1.可设置允许输入的最大最小值
    2.可设置精度
    3.限制非数值输入

    输入限制

    1.小数点"."不允许出现在第一位,且只允许输入一次
    2.负号"-"仅可以出现在第一位,且配置最小值允许出现负值时可用
    3.限制输入法的输入事件

    未实现功能TODO/(ㄒoㄒ)/~~

    精度拦截目前在输入时未做拦截
    原因:在输入框输入达到精度限制时,此时按ctrl+a想要执行覆盖选中重新输入操作时,输入事件会判断达到输入精度做大值,无法执行上述操作
    替换方案:在输入框失去焦点时做精度格式化

    有解决方案的小伙伴欢迎解答 😀T_T

    demo如下👇

    提供三个参数
    {min: -100, max: 100, precision: 2},
    1.min最小值:默认-100
    2.max最小值:默认100
    3.precision精度(保留小位数):默认2

    '懒人'提醒

    可根据需求修改默认值,或设置为null不做限制
    只需将demo中对应的监听事件里 声明的 _min 和 _max 和 _precision 改为想要的默认值即可

    //keypress下
    let _precision = 2;
    let _max = 100;
    let _min = -100;
    //keyup下
    let _precision = 2;
    let _max = 100;
    let _min = -100;
    //focusout
    let _precision = 2;
    
    <template>
      <div class="hello">
        <el-input
          type="text"
          v-model="test"
          v-only-number="{ min: -100, max: 100, precision: 2 }"
        ></el-input>
    </template>
    
    <script>
    export default {
      name: "HelloWorld",
      directives: {
        onlyNumber: {
          // 只调用一次,第一次绑到元素时调用。在这里可以进行一次性的初始化设置。
          bind: function (el, vDir) {
            let dom = el.tagName == "INPUT" ? el : el.querySelector("input");
            dom.placeholder = "请输入数值" + JSON.stringify(vDir.value);
          },
          // 当被绑定的元素插入到 DOM 中时
          inserted: function (el, vDir) {
            let dom = el.tagName == "INPUT" ? el : el.querySelector("input");
            //记录当前值
            let content = dom.value;
            //插槽参数
            let config = vDir.value;
    
            /**
             * @function 输入有效值监听事件
             * @description 只允许输入 数字/小数点/负号
             */
            el.addEventListener("keypress", (e) => {
              //阻止输入
              function preventInput() {
                if (e.preventDefault) {
                  e.preventDefault();
                } else {
                  e.returnValue = false;
                }
              }
              let re = /\d|\.|-/; //只允许输入 数字/小数点/负号
              let key = e.key; //输入值
              content = e.target.value; //输入值生效前的值
              //配置
              let _precision = 2;
              let _max = 100;
              let _min = -100;
              if (config) {
                _precision = parseInt(config.precision);
                _max = parseFloat(config.max);
                _min = parseFloat(config.min);
              }
              if (!re.test(key)) {
                preventInput();
              } else if ((content.indexOf(".") > 0 || !content) && key == ".") {
                // .不允许出现在第一位,且只允许输入一次
    
                preventInput();
              } else if ((_min >= 0 || content) && key == "-") {
                // "-"号仅可以出现在第一位,且配置最小值允许出现负值
    
                preventInput();
              } else if (
                // 精度拦截
                content.split("").reverse().join("").indexOf(".") == _precision
              ) {
                // preventInput();
              }
            });
            el.addEventListener("keyup", (e) => {
              let value = e.target.value; //输入值生效后的值
              //输入非数值,keypress已过滤,此处过滤输入法输入中文情况
              if (isNaN(value) && value !== "-") {
                e.target.value = content;
                return false;
              }
    
              content = value;
              //精度
              let _precision = 2;
              let _max = 100;
              let _min = -100;
              if (config) {
                _precision = parseInt(config.precision);
                _max = parseFloat(config.max);
                _min = parseFloat(config.min);
              }
    
              if (value > _max) {
                e.target.value = _max;
                content = _max;
              }
              if (value < _min) {
                e.target.value = _min;
                content = _min;
              }
            });
            el.addEventListener("focusout", (e) => {
              let value = e.target.value;
              //精度
              let _precision = 2;
              if (config) {
                _precision = parseInt(config.precision);
              }
              e.target.value =
                value != "" ? parseFloat(value).toFixed(_precision) : "";
    
              dom.dispatchEvent(new Event("input"));
            });
          },
        },
      },
      data() {
        return {
          test: "",
        };
      },
      
      watch:{
        test(){
          console.log('watch test',this.test)
        }
      }
    };
    
    </script>
    

    相关文章

      网友评论

          本文标题:【directives】自定义指令之input数值

          本文链接:https://www.haomeiwen.com/subject/afgvvrtx.html