Vue指令的钩子函数使用方法


Posted in Javascript onMarch 20, 2017

在Vue 中可以把一系列复杂的操作包装为一个指令。

什么是复杂的操作?

我的理解是:复杂逻辑功能的包装、违背数据驱动的 DOM 操作以及对一些 Hack 手段的掩盖等。我们总是期望以操作数据的形式来实现功能逻辑。

钩子函数

对于自定义指令的定义,Vue2 有 5 个可选的钩子函数。

bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。
componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
unbind: 只调用一次,指令与元素解绑时调用。

接下来,定义一个简单的指令以验证这些钩子函数的触发时机。

template

<div id="app">
 <my-comp v-if="msg" :msg="msg"></my-comp>
 <button @click="update">更新</button>
 <button @click="uninstall">卸载</button>
 <button @click="install">安装</button>
</div>

script

Vue.directive('hello', {
 bind: function (el) {
  console.log('bind')
 },
 inserted: function (el) {
  console.log('inserted')
 },
 update: function (el) {
  console.log('update')
 },
 componentUpdated: function (el) {
  console.log('componentUpdated')
 },
 unbind: function (el) {
  console.log('unbind')
 }
})
var myComp = {
 template: '<h1 v-hello>{{msg}}</h1>',
 props: {
  msg: String
 }
}
new Vue({
 el: '#app',
 data: {
  msg: 'Hello'
 },
 components: {
  myComp: myComp
 },
 methods: {
  update: function () {
   this.msg = 'Hi'
  },
  uninstall: function () {
   this.msg = ''
  },
  install: function () {
   this.msg = 'Hello'
  }
 }
})

页面加载时

bind
inserted

组件更新时

点击“更新”按钮,更改数据触发组件更新。

update
componentUpdated

卸载组件时

点击“卸载”按钮,数据置空否定判断以触发组件卸载。

unbind

重新安装组件时

点击“安装”按钮,数据赋值肯定判断以触发组件重新安装。

bind
inserted

区别

从案例的运行中,对 5 个钩子函数的触发时机有了初步的认识。存疑的也就是bindinserted、updatecomponentUpdated的区别了。

bind 和 inserted

据文档所说,插入父节点时调用 inserted,来个测试。

bind: function (el) {
 console.log(el.parentNode) // null
 console.log('bind')
},
inserted: function (el) {
 console.log(el.parentNode) // <div id="app">...</div>
 console.log('inserted')
}

分别在两个钩子函数中输出父节点:bind 时父节点为 null,inserted 时父节点存在。

update 和 componentUpdated

关于这两个的介绍,从字眼上看感觉是组件更新周期有关,继续验证。

update: function (el) {
 console.log(el.innerHTML) // Hello
 console.log('update')
},
componentUpdated: function (el) {
 console.log(el.innerHTML) // Hi
 console.log('componentUpdated')
}

没毛病,update 和 componentUpdated 就是组件更新前和更新后的区别。

结论

文档说的没错……
Demo

最佳实践

根据需求的不同,我们要选择恰当的时机去初始化指令、更新指令调用参数以及释放指令存在时的内存占用等。

比较常见的场景是:用指令包装一些无依赖的第三方库以扩展组件功能。而一个健壮的库通常会包含:初始化实例、参数更新和释放实例资源占用等操作。

Vue.directive('hello', {
 bind: function (el, binding) {
  // 在 bind 钩子中初始化库实例
  // 如果需要使用父节点,也可以在 inserted 钩子中执行
  el.__library__ = new Library(el, binding.value)
 },
 update: function (el, binding) {
  // 模版更新意味着指令的参数可能被改变,这里可以对库实例的参数作更新
  // 酌情使用 update 或 componentUpdated 钩子
  el.__library__.setOptions(Object.assign(binding.oldValue, binding.value))
 },
 unbind: function (el) {
  // 释放实例
  el.__library__.destory()
 }
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery EasyUI API 中文文档 - Menu菜单
Oct 03 Javascript
jquery scrollTop方法根据滚动像素显示隐藏顶部导航条
May 27 Javascript
jquery ajax修改全局变量示例代码
Nov 08 Javascript
jquery的总体架构分析及实现示例详解
Nov 08 Javascript
javascript比较两个日期的先后示例代码
Dec 31 Javascript
jQueryMobile之Helloworld与页面切换的方法
Feb 04 Javascript
JavaScript实现添加、查找、删除元素
Jul 02 Javascript
javascript实现将文件保存到本地方法汇总
Jul 26 Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
Nov 15 Javascript
解析javascript瀑布流原理实现图片滚动加载
Mar 10 Javascript
javascript中利用柯里化函数实现bind方法
Apr 29 Javascript
Vue ElementUI之Form表单验证遇到的问题
Aug 21 Javascript
非常实用的vue导航钩子
Mar 20 #Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
Mar 20 #Javascript
如何解决vue与传统jquery插件冲突
Mar 20 #Javascript
Vue.js路由vue-router使用方法详解
Mar 20 #Javascript
Vue插件写、用详解(附demo)
Mar 20 #Javascript
详解vue事件对象、冒泡、阻止默认行为
Mar 20 #Javascript
javascript使用btoa和atob来进行Base64转码和解码
Mar 20 #Javascript
You might like
解析mysql中UNIX_TIMESTAMP()函数与php中time()函数的区别
2013/06/24 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
Js的MessageBox
2006/12/03 Javascript
jQuery 版本的文本输入框检查器Input Check
2009/07/09 Javascript
js open() 与showModalDialog()方法使用介绍
2013/09/10 Javascript
javascript控制Div层透明属性由浅变深由深变浅逐渐显示
2013/11/12 Javascript
javascript中sort()的用法实例分析
2015/01/30 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
Vue.js自定义事件的表单输入组件方法
2018/03/08 Javascript
vue实现引入本地json的方法分析
2018/07/12 Javascript
vue如何根据网站路由判断页面主题色详解
2018/11/02 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
解决vue单页面修改样式无法覆盖问题
2019/08/05 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python基础教程之面向对象的一些概念
2014/08/29 Python
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
Python判断Abundant Number的方法
2015/06/15 Python
详解python并发获取snmp信息及性能测试
2017/03/27 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
Python常用数字处理基本操作汇总
2020/09/10 Python
用python计算文件的MD5值
2020/12/23 Python
SpringBoot首页设置解析(推荐)
2021/02/11 Python
html5 Canvas画图教程(5)—canvas里画曲线之arc方法
2013/01/09 HTML / CSS
Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
2015/01/27 面试题
环境工程与管理大学毕业生求职信
2013/10/02 职场文书
幼儿园教师请假制度
2014/01/16 职场文书
社区精神文明建设汇报材料
2014/08/17 职场文书
html5移动端禁止长按图片保存的实现
2021/04/20 HTML / CSS
LayUI+Shiro实现动态菜单并记住菜单收展的示例
2021/05/06 Javascript
进行数据处理的6个 Python 代码块分享
2022/04/06 Python
Golang实现可重入锁的示例代码
2022/05/25 Golang