vue directive自定义指令 2.0和3.0

108 阅读3分钟

vue2.0

对DOM元素进行操作可能会需要自定义指令,Vue.directive(name, options),name是指令名(没有v-),options可以理解为配置项,其中比较重要的是各个钩子函数

Vue.directive('focus', {
  // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一些一次性的初始化设置
  bind:function(el, binding, vnode, oldVnode) {
    console.log(el, binding, vnode, oldVnode)
  },
  // 被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入到文档中)。例如如果我们想实现一个文本框自动聚焦的指令,那么就应该要用到这个钩子
  inserted:function(el, binding, vnode, oldVnode) { },
  // 所在组件的vnode更新时调用,但可能发生在其子vnode更新之前。也就是说有可能子组件还没有更新完成,这个钩子就已经触发了
  update:function(el, binding, vnode, oldVnode) { },
  // 指令所在组件的vNode及其子vNode全部更新后调用。所以一般涉及到组件更新的我们都会使用该钩子函数而不是用上面的update
  componentUpdata:function(el, binding, vnode, oldVnode) { },
  // 与bind一样也是只调用一次,指令在与元素解绑是调用
  unbind:function(el, binding, vnode, oldVnode) { }
})
  • el:指令所绑定的元素,可以用来直接操作 DOM
  • binding:一个对象,包含以下属性:
    • name:指令名,不包括 v- 前缀;
    • value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2;
    • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用;
    • expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”;
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”;
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true };
  • vnode:Vue 编译生成的虚拟节点。一般用不到
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。一般不用

学习参考 Vue2.0如何实现一个自定义指令(搜一贼)

vue3.0

vue3.0中vue是通过函数createApp()来返回一个vue实例app,因此使用app.directive(name,options)创建自定义指令,指令参数没有改变,仍然是name和options

const app = createApp()
//全局自定义指令
app.directive('focus',{ mounted(el){ el.focus() } })
//组件使用 
<input type="text" v-focus />
  • 钩子函数(可选某个或多个钩子函数使用)

    • created :在绑定元素的attribute或者事件监听器被应用之前调用。比如某元素需要绑定一个click事件,同时该元素还应用了自定义指令,那么在该元素绑定click事件之前便会出发自定义指令的created钩子函数。3.0中新增
    • beforeMounted :当指令第一次绑定到元素并且在挂载父组件之前调用。类似2.0中的bind
    • mounted :在绑定元素的父组件被挂载后调用。类似2.0中inserted。
    • beforeUpdate :在更新包含组件的VNode之前调用。3.0中新增。
    • updated :在包含组件的VNode及其子组件的VNode更新后调用。类似2.0中的componentUpdate。
    • beforeUnmounted :在卸载绑定元素的父组件之前调用。3.0中新增
    • unmounted :当指令与元素解除绑定且父组件已卸载时,只调用一次。类似2.0中的unbind

而3.0中钩子函数的参数依然还是4个(el, binding, vNode, prevNode),并且与2.0中的以一样的,唯一不同的是第四个参数名称变成了prevNode,其作用还是相同的。

const app = createApp();
app.directive('focus',{
    created(el,binding,vnode,prevNode){},
    beforeMount(el,binding,vnode,prevNode){},
    mounted(el,binding,vnode,prevNode){},
    beforeUpdate(el,binding,vnode,prevNode){},
    updated(el,binding,vnode,prevNode){},
    beforeUnmount(el,binding,vnode,prevNode){},
    unmounted(el,binding,vnode,prevNode){}
})

学习参考 so easy 的 Vue3.0自定义指令(也搜一贼)