vue directives 使用详解

7,714 阅读2分钟

自定义指令钩子的执行顺序

点击 codepen 查看指令钩子函数的执行顺序

    created() {
      console.log('created')
    },
    mounted() {
      console.log('mounted')
    },
    directives:{
      focus:{
        inserted(el){
          console.log('inserted-el',el)
        },
        bind(el) {
          console.log('bind-el',el)
        },
        update(el) {
          console.log('directives-update',el)
        }
      }
    },
    updated() {
      console.log('updated')
    },

当我们加载页面的时候执行顺序

created
bind-el <input data-v-c2165916 type=​"text">​
inserted-el <input data-v-c2165916 type=​"text">​
mounted

当我们更新 input 输入框的值的时候

directives-update <input data-v-c2165916 type=​"text">​
updated

钩子函数参数

绑定后可以拿到的参数

<input type="text" v-focus v-model="value" />
    directives:{
      focus:{
        inserted(el,binding){
          console.log('inserted-el',el,binding)
        }
      }
    }

如何向自定义指令传递参数

传递 arg

格式: v-focus:arg, arg 传递的参数会被当作字符串类型的,通过 binding.arg 接收

<input type="text" v-focus:type1 v-model="value" />
<input type="text" v-focus:{age:1} v-model="value" />
    directives:{
      focus:{
        inserted(el,binding){
          console.log('inserted-el',binding)
        }
      }
    }

传递 value

格式: v-focus="value" ,这里的 value 是变量名,而不是字符串。

<input type="text" v-focus="format1" v-model="value" />
    data() {
      return {
        value:'',
        format1:'date'
      }
    },

可以看到,通过绑定 value ,指令中接收的 binding 多了个 value 的属性,值就我们传递进来的变量值。而且还多了一个 expression ,expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

修饰符

格式: v-focus.isFocus, 修饰符对象为: {isFocus:true}

<input type="text" v-focus.isFocus v-model="value" />
    data() {
      return {
        value:''
      }
    },

实践:数字格式化指令

/**
 * 根据 v-numeral 绑定的类型来格式input输入的值,并通过执行绑定的函数传递出去
 * 格式1: digit-number。 如 v-numeral:digit-2="handle" 保留2位小数
 *       将 '12312.123' -> '12312.12'
 * 格式1: amount 如 v-numeral:amount-3="handle"
 *       将 '1123123.123' -> '1,123,123.123'
 * 上面两种形式不传保留位数默认保留整数
 * 需要传入一个 handle 函数,函数接收处理好的值
 * 使用如: <el-input class="w180" v-model="maxAssignNum" v-numeral:amount-3="handle"></el-input>
 * 如果只需要保留整数使用: <el-input v-model="maxAssignNum" v-numeral="handle"></el-input>
 */
Vue.directive('numeral', {
  bind: function(el, binding) {
    // 找到绑定元素下的input元素
    const input = el.hasChildNodes() ? el.getElementsByTagName('input')[0] : el
    const { value: fn, arg } = binding
    if (typeof fn !== 'function') {
      return console.error(
        'The value of directive "v-numeral" must be a function!'
      )
    }
    el.addEventListener('change', function(e) {
      let value = e.target.value

      let float = parseFloat(value)
      if (isNaN(float)) {
        fn('')
        return
      }
      numeralHandlers.adapt(arg, float, fn)
    })
  }
})

该指令有如下功能

  • 可以设置保留几位小数
  • 可以设置格式化形式:整数、金额类每三位一个逗号。并且使用适配的模式,后序要新增其他模式也是很方便不会影响到之前的代码逻辑

点击 codepen 地址查看:数字格式化指令的完整代码