Vue 自定义指令

439 阅读1分钟

Vue自定义指令

定义

通过directive方法,配合钩子函数及参数定义指令

定义全局自定义指令

// js
  Vue.directive('focus', {
    inserted (el, binding, vnode, oldVnode) {
      el.focus()
      console.log('inserted', el, binding, vnode, oldVnode)
    },
    bind (el, binding, vnode, oldVnode) {
      console.log('bind', el, binding, vnode, oldVnode)
    },
    unbind (el, binding, vnode, oldVnode) {
      console.log('unbind', el, binding, vnode, oldVnode)
    },
    update (el, binding, vnode, oldVnode) {
      console.log('update', el, binding, vnode, oldVnode)
    },
    componentUpdated (el, binding, vnode, oldVnode) {
      console.log('componentUpdated', el, binding, vnode, oldVnode)
    }
  })

定义局部自定义指令

directives: {
      reverse: {
        inserted (el, binding, vnode, oldVnode) {
          console.log('directives inserted', el, binding, vnode, oldVnode)
        },
        bind (el, binding, vnode, oldVnode) {
          console.log('directives bind', el, binding, vnode, oldVnode)
        },
        unbind (el, binding, vnode, oldVnode) {
          console.log('directives unbind', el, binding, vnode, oldVnode)
        },
        update (el, binding, vnode, oldVnode) {
          console.log('directives update', el, binding, vnode, oldVnode)
        },
        componentUpdated (el, binding, vnode, oldVnode) {
          console.log('directives componentUpdated', el, binding, vnode, oldVnode)
          el.value = binding.value.split('').reverse().join('')
        }
      }
    }

自定义指令使用

// html
<input type="text" v-focus.bar="message">

自定义指令 钩子函数 & 参数

  • 通过directive方法,配合钩子函数及参数定义指令

钩子函数

  • inserted: 被绑定元素插入父节点时调用
  • bind: 指令被绑定时调用
  • unbind: 指令解绑时调用,如 $destory()
  • update: 组件更新时调用
  • componentUpdated: 组件更新后完成调用

参数

  • el: HTML元素
  • binding: 自定义组件信息,如:v-focus.bar="message" & v-blur:foo="value"
    • name 自定义指令名称,除v-,如:foucs、blur
    • value 自定义指令值 hello vue !。指令可以接受合法JS表达式。
    • oldValue 上一个值
    • expression 自定义指令表达式,如:message。
    • arg 参数,如foo
    • modifiers 修饰符 bar,返回 {bar: true}
  • vnode: 虚拟节点
  • oldVnode: 上一个虚拟节点,仅在update、componentUpdated中可用

函数简写 & 动态参数指令

一般情况下 bind和update触发行为相同,所以可以简写为同一个回调函数

 Vue.directive('pin', function (el, binding) {
    console.log(binding)
    el.style.position = 'fixed'
    el.style[binding.arg] = binding.value
  })

在模板中使用v-pin指令,使div改变位置

<div v-pin:[dir]="200 + 'px'">
自定义指令
</div>

v-pin的参数dir设置

var app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue !',
      dir: 'left'
    },
    methods: {
      onInput (val) {
        this.message = val
      }
    }
  })

完成代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>自定义指令</title>
  <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
  {{message}}
  <field v-model="message"></field>
  <input type="text" v-focus.bar="message">
  <div v-pin:[dir]="200 + 'px'">
    自定义指令
  </div>
</div>
<script>
  Vue.component('field', {
    props: {
      value: {
        type: String
      }
    },
    // 局部自定义指令
    directives: {
      reverse: {
        inserted (el, binding, vnode, oldVnode) {
          console.log('directives inserted', el, binding, vnode, oldVnode)
        },
        bind (el, binding, vnode, oldVnode) {
          console.log('directives bind', el, binding, vnode, oldVnode)
        },
        unbind (el, binding, vnode, oldVnode) {
          console.log('directives unbind', el, binding, vnode, oldVnode)
        },
        update (el, binding, vnode, oldVnode) {
          console.log('directives update', el, binding, vnode, oldVnode)
        },
        componentUpdated (el, binding, vnode, oldVnode) {
          console.log('directives componentUpdated', el, binding, vnode, oldVnode)
          el.value = binding.value.split('').reverse().join('')
        }
      }
    },
    template: `
      <input :value="value" @input="onInput" v-reverse:foo="value">
    `,
    methods: {
      onInput (e) {
        var value = e.target.value
        this.$emit('input', value)
      }
    }
  })
  // 全局自定义指令
  Vue.directive('focus', {
    inserted (el, binding, vnode, oldVnode) {
      el.focus()
      console.log('inserted', el, binding, vnode, oldVnode)
    },
    bind (el, binding, vnode, oldVnode) {
      console.log('bind', el, binding, vnode, oldVnode)
    },
    unbind (el, binding, vnode, oldVnode) {
      console.log('unbind', el, binding, vnode, oldVnode)
    },
    update (el, binding, vnode, oldVnode) {
      console.log('update', el, binding, vnode, oldVnode)
    },
    componentUpdated (el, binding, vnode, oldVnode) {
      console.log('componentUpdated', el, binding, vnode, oldVnode)
    }
  })
  /**
   * example
   * 函数简写 & 动态参数指令
   * 一般情况下 bind和update触发行为相同,所以可以简写为同一个回调函数
   */
  Vue.directive('pin', function (el, binding) {
    console.log(binding)
    el.style.position = 'fixed'
    el.style[binding.arg] = binding.value
  })
  var app = new Vue({
    el: '#app',
    data: {
      message: 'hello vue !',
      dir: 'left'
    },
    methods: {
      onInput (val) {
        this.message = val
      }
    }
  })
</script>
</body>
</html>