总结下vue的自定义指令

506 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

前言

之前我讲了vue自带的指令,学习下vue的指令(1)学习下vue的指令(2),自带的指令能满足大部分场景了,但是我们有时候需要对针对dom定义一些交互,于是vue就支持通过自定义指令来实现。

下面就来总结下vue的自定义指令。

自定义指令

有全局和组件两种方式设置。

全局方式

Vue.directives('xxx', {
  bind (el, binding, VNode, oldVNode) {
   // 自定义操作
  }
})

组件方式

  directives: {
   xxx:{
     bind (el, binding, VNode, oldVNode) {
       // 自定义操作
     }
   }
  },

xxx 就是指令名。调用的时候通过v-xxx

<div v-xxx="value"></div>

钩子函数

下面来讲讲自定义指令的钩子函数,也就是上面的bind函数,这是其中一种钩子函数

还有inserted,update, componentUpdatedunbind

  • bind

    绑定到dom元素的时候调用,只调用一次。

  • inserted

    被绑定元素插入到父节点时调用。

  • update

    组件虚拟dom更新时调用,但是不一定能保证顺序,可能在子组件虚拟dom之前更新。

  • componentUpdated

    在组件虚拟dom和子组件虚拟dom都更新后调用

  • bind

    dom元素与指令解绑的时候调用,只调用一次。

参数

钩子函数都有共同的参数(el, binding,VNode, oldVNode

下面来讲讲这些共同参数。

  • el

    当前绑定的dom元素

  • binding

    描述对象,有以下属性

    • name: 指令名,也就是上面的xxx

    • rawName: 指令全名,比如v-xxx:a.b(包含v-,如果有参数/修饰符,也会包含)

    • value: 这个是指令后面的value。 比如v-xxx="value"

    • oldValue: value的上一个旧值

    • arg: 这个获取指令后面的参数。以冒号为标识。比如v-xxx:a="value",获得的就是a

    • modifiers: 对象类型,这个是修饰符。一般是跟着参数后面,以.分割,比如v-xxx:arg.b.c="value",获得的就是{b:true,c:true}

    • expression value的字符串形式,比如v-xxx="value",获得的就是字符串value.

例子

下面通过例子来说明钩子和参数

钩子

   <div>
    <div v-xxx="name" v-if="name">{{name}}</div>
    <button @click="name ='aa'">设置</button>
    <button @click="name =''">隐藏</button>
  </div>
  directives: {
    xxx: {
      bind () {
        console.log('bind')
      },
      inserted () {
        console.log('inserted')
      },
      update () {
        console.log('update')
      },
      componentUpdated () {
        console.log('componentUpdated')
      },
      unbind () {
        console.log('unbind')
      }
    }
  }

执行顺序如下:

image.png

页面渲染会先执行bindinserted钩子,然后点击设置按钮,会执行updatecomponentUpdated钩子,最后点击隐藏按钮,会执行unbind钩子。

参数

  <div v-xxx:a.b.c="name">答案cp3</div>
  directives: {
    xxx: {
      bind (el, binding, VNode, oldVNode) {
        console.log(el, binding)
        console.log(VNode, oldVNode)
      }
    }
  },

image.png

image.png