VUE自定义指令详解

在vue,我们经常会遇到一种需求,不允许输入某些值,比如在输入框中只允许输入两位,不允许输入特殊符号等等。那么就可以用到vue自定义指令啦

我们先来看看什么是自定义指令

vue.directive是我们除了内置的指令(如v-model和v-show)之外的自定义指令。自定义指令是对普通DOM元素进行的底层操作,它是一种有效的的补充和扩展,不仅可以用于定义任何的dom操作,并且是可以复用的

了解完了我们来看看具体如何使用吧
我们更倾向于把封装的自定义指令文件放到utils文件下。新建一个js文件。然后就可以直接定义啦。先看我定义的指令吧

const inputLimit = {
  install (Vue, options) {
    Vue.directive("input-limit", {
      bind(el, binding) {
        var wins_0 = /[^\d]/g //整数判断
        var wins_1 = /[^\d^\.]/g //小数判断
        var wins_2 = /[^(\-)0-9]/g //允许输入-号
        var wins_3 = /[^(\-*)A-Z0-9]/g //允许输入英文及-号
        var flag = true;
        var points = 0;
        var lengths = 0
        var remainder = 0
        var no_int = 0
        const target = el instanceof HTMLInputElement ? el : el.querySelector("input");
        target.addEventListener("compositionstart", e => {
          flag = false;
        });
        target.addEventListener("compositionend", e => {
          flag = true;
        });
        target.addEventListener("input", e => {
          setTimeout(function() {
            if (flag) {
              if (binding.value == 0) {
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_0, "");
                  e.target.dispatchEvent(new Event("input")) //手动更新v-model值
                }
              }
              if (binding.value == 1) {
                if (wins_0.test(e.target.value.toString().replace(/\d+\.(\d*)/, '$1'))) {
                  remainder = true
                }
                if ((e.target.value.split('.')).length - 1 > 1) {
                  points = true
                }
                if (e.target.value.toString().split(".")[1] != undefined) {
                  if (e.target.value.toString().split(".")[1].length > 1) {
                    lengths = true
                  }
                }
                if (e.target.value.toString().indexOf(".") != -1) {
                  no_int = false
                } else {
                  no_int = true
                }
                if (wins_1.test(e.target.value) || lengths || points || remainder) {
                  if (!no_int) {
                    e.target.value = e.target.value.replace(wins_1, "").replace('.', '$#$').replace(/\./g, '').replace(
                      '$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').substring(0, e.target.value.indexOf(
                      ".") + 2)
                  } else {
                    e.target.value = e.target.value.replace(wins_0, "")
                  }
                  e.target.dispatchEvent(new Event("input"))
                }
              }


              if (binding.value == 2) {
                if (wins_0.test(e.target.value.toString().replace(/\d+\.(\d*)/, '$1'))) {
                  remainder = true
                }
                if ((e.target.value.split('.')).length - 1 > 1) {
                  points = true
                }
                if (e.target.value.toString().split(".")[1] != undefined) {
                  if (e.target.value.toString().split(".")[1].length > 2) {
                    lengths = true
                  }
                }
                if (e.target.value.toString().indexOf(".") != -1) {
                  no_int = false
                } else {
                  no_int = true
                }
                if (wins_1.test(e.target.value) || lengths || points || remainder) {
                  if (!no_int) {
                    e.target.value = e.target.value.replace(wins_1, "").replace('.', '$#$').replace(/\./g, '').replace(
                      '$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').substring(0, e.target.value.indexOf(
                      ".") + 3)
                  } else {
                    e.target.value = e.target.value.replace(wins_0, "")
                  }
                  e.target.dispatchEvent(new Event("input"))
                }
              }

              if (binding.value == 3) {
                if (wins_0.test(e.target.value.toString().replace(/\d+\.(\d*)/, '$1'))) {
                  remainder = true
                }
                if ((e.target.value.split('.')).length - 1 > 1) {
                  points = true
                }
                if (e.target.value.toString().split(".")[1] != undefined) {
                  if (e.target.value.toString().split(".")[1].length > 3) {
                    lengths = true
                  }
                }
                if (e.target.value.toString().indexOf(".") != -1) {
                  no_int = false
                } else {
                  no_int = true
                }
                if (wins_1.test(e.target.value) || lengths || points || remainder) {
                  if (!no_int) {
                    e.target.value = e.target.value.replace(wins_1, "").replace('.', '$#$').replace(
                    /\./g, '').replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d\d).*$/, '$1$2.$3').substring(
                    0, e.target.value.indexOf(
                      ".") + 4)
                  } else {
                    e.target.value = e.target.value.replace(wins_0, "")
                  }
                  e.target.dispatchEvent(new Event("input"))
                }
              }
              if(binding.value == 4){
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_2, "");
                  e.target.dispatchEvent(new Event("input"))
                }
                
              }
              if(binding.value == 5){
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_1, "");
                  e.target.dispatchEvent(new Event("input")) //手动更新v-model值
                }
                
              }
              if (binding.value == 6) {
                if (wins_0.test(e.target.value.toString().replace(/\d+\.(\d*)/, '$1'))) {
                  remainder = true
                }
                if ((e.target.value.split('.')).length - 1 > 1) {
                  points = true
                }
                if (e.target.value.toString().split(".")[1] != undefined) {
                  if (e.target.value.toString().split(".")[1].length > 6) {
                    lengths = true
                  }
                }
                if (e.target.value.toString().indexOf(".") != -1) {
                  no_int = false
                } else {
                  no_int = true
                }
                if (wins_1.test(e.target.value) || lengths || points || remainder) {
                  if (!no_int) {
                    e.target.value = e.target.value.replace(wins_1, "").replace('.', '$#$').replace(/\./g, '').
                    replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d\d\d\d\d).*$/, '$1$2.$3').substring(0, e.target.value.indexOf(
                      ".") + 7)
                  } else {
                    e.target.value = e.target.value.replace(wins_0, "")
                  }
                  e.target.dispatchEvent(new Event("input"))
                }
              }
              if(binding.value == 7){
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_3, "");
                  e.target.dispatchEvent(new Event("input"))
                }
                
              }
            }
          }, 0)
        })
      }
    })
    Vue.directive("input-limit-zhEmoji", {
      bind(el, binding) {
        var wins_0 = /[^\u0000-\u00FF]|[`~#$%^&*()_\+=<>?:"{}|\/;'\\[\]·~!#¥%……&*()\+={}|《》?:“”【】、;‘',。、]/im; //不许输入中文及以上特殊字符
        var flag = true;
        const target = el instanceof HTMLInputElement ? el : el.querySelector("input");
        target.addEventListener("compositionstart", e => {
          flag = false;
        });
        target.addEventListener("compositionend", e => {
          flag = true;
        });
        target.addEventListener("input", e => {
          setTimeout(function() {
            if (flag) {
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_0, "");
                  e.target.dispatchEvent(new Event("input")) //手动更新v-model值
                }
            }
          }, 0)
        })
      }
    })
    Vue.directive("input-limit-phone", {
      bind(el, binding) {
        var wins_0 = /[^\d+|-]/g //只许输入准确的电话
        var flag = true;
        const target = el instanceof HTMLInputElement ? el : el.querySelector("input");
        target.addEventListener("compositionstart", e => {
          flag = false;
        });
        target.addEventListener("compositionend", e => {
          flag = true;
        });
        target.addEventListener("input", e => {
          setTimeout(function() {
            if (flag) {
                console.log( e.target.value)
                if (wins_0.test(e.target.value)) {
                  e.target.value = e.target.value.replace(wins_0, "");
                  e.target.dispatchEvent(new Event("input")) //手动更新v-model值
                }
            }
          }, 0)
        })
      }
    })
  },
}
export default inputLimit


这是我定义的自定义指令。如果能看懂的话应该是可以举一反三的。主要是通过正则去校验。自定义指令创建好了。我们该怎么使用呢,为了方便,我们一般是在main.js里面全局引用。这样就不管在那个vue文件下都可以使用啦

import inputLimit from '@/utils/inputLimit'
Vue.use(inputLimit)

这样就全局注册啦。但是博主这里配置了路径别名可以直接使用@符。如果没有配置路径别名的话还请小伙伴正确引用路径

最后我们看下具体如何使用

<el-input type="text" input-limit-phone  v-model.trim="formData.totalAmount"></el-input>  //只允许输入准确的电话
<el-input type="text" v-input-limit="0" v-model.trim="formData.totalAmount"></el-input> //只允许输入整数

你可能感兴趣的:(vue.js,javascript,前端)