前言

除了核心功能默认内置的指令 (v-model 和 v-show),vue 也允许注册自定义指令。

官网介绍的比较抽象,显得很高大上,我个人对自定义指令的理解是:当自定义指令作用在一些dom元素或组件上时,该元素在初次渲染、插入到父节点、更新、解绑时可以执行一些特定的操作(钩子函数()

自定义指令有两种注册方式,一种是全局注册,使用vue.directive(指令名,配置参数)注册,注册之后所有的vue实例都可以使用,另一种是局部注册,在创建vue实例时通过directives属性创建局部指令,局部自定义指令只能在当前vue实例内使用

自定义指令可以绑定如下钩子函数:

·bind      ;只调用一次,元素渲染成dom节点后,执行directives模块的初始化工作时调用,在这里可以进行一次性的初始化设置。
·inserted       ;被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
·update       ;所在组件的 vnode 更新时调用,但是可能发生在其子 vnode 更新之前。指令的值可能发生了改变,也可能没有。
·componentupdated ;指令所在组件的 vnode 及其子 vnode 全部更新后调用。
·unbind       ;只调用一次,指令与元素解绑时调用。

每个钩子函数可以有四个参数,分别是el(对应的dom节点引用)、binding(一些关于指令的扩展信息,是个对象)、vnode(该节点对应的虚拟vn哦的)和oldvnode(之前的vnode,仅在update和componentupdated钩子中可用)

bind钩子函数执行的时候该dom元素被渲染出来了,但是并没有插入到父元素中,例如:

输出如下:

可以看到input元素自动获得焦点了,控制台输出如下:

可以看到对于bind()钩子来说,它的父节点是获取不到的,因为vue内部会在执行bind()钩子后才会将当前元素插入到父元素的子节点里

源码分析

在解析模板将dom转换成ast对象的时候会执行processattrs()函数,如下:

adddirective会给ast对象上增加一个directives属性保存指令信息,如下:

例子里的p元素执行到这里时对应的ast对象如下:

接下来在generate生成rendre函数的时候,会执行gendirectives()函数,将ast转换成一个render函数,如下:

最后等渲染完成后会执行directives模块的create钩子函数,如下:

_updat 就是处理指令初始化和更新的,如下:

writer by:大沙漠 qq:22969969

对于bind钩子函数来说是直接执行了,而对于inserted钩子函数则是把函数保存到dirswithinsert数组里,再定义了一个callinsert函数,该函数内部通过作用域访问dirswithinsert变量,并遍历该变量依次执行每个inserted钩子函数

mergevnodehook()钩子函数的作用是把insert作为一个hooks属性保存到对应的vnode的data上面,当该vnode插入到父节点后会调用该hooks,如下:

createfninvoker就是v-on指令对应的那个函数,用到了同一个api,执行完后,我们就把invoker插入到input对应的vnode.data.hook里了,如下:

最后等到该vnode插入到父节点后就会执行invokecreatehooks()函数,该函数会遍历vnode.hook.insert,依次执行每个函数,也就执行到我们自定义定义的inserted钩子函数了。

总结

到此这篇关于vue.js源码分析之自定义指令的文章就介绍到这了,更多相关vue.js自定义指令内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!