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 相关文章推荐
经典的解除许多网站无法复制文字的绝招
Dec 31 Javascript
几行代码轻松搞定jquery实现flash8类似的连接效果
May 03 Javascript
基于KMP算法JavaScript的实现方法分析
May 03 Javascript
javascript动态的改变IFrame的高度实现自动伸展
Oct 12 Javascript
JavaScript中实现继承的三种方式和实例
Jan 29 Javascript
使用Raygun对Node.js应用进行错误处理的方法
Jun 23 Javascript
快速掌握WordPress中加载JavaScript脚本的方法
Dec 17 Javascript
jQuery Datatable 多个查询条件自定义提交事件(推荐)
Aug 24 jQuery
javascript实现数字配对游戏的实例讲解
Dec 14 Javascript
JS中双击和单击事件冲突的解决方法
Apr 09 Javascript
layui-table对返回的数据进行转变显示的实例
Sep 04 Javascript
JS禁用右键、禁用Ctrl+u、禁用Ctrl+s、禁用F12的实现代码
Dec 01 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
PHP读取MySQL数据代码
2008/06/05 PHP
php 注册时输入信息验证器的实现详解
2013/07/05 PHP
CodeIgniter基本配置详细介绍
2013/11/12 PHP
splice slice区别
2006/10/09 Javascript
Dojo 学习要点
2010/09/03 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
javascript实现yield的方法
2013/11/06 Javascript
javascript实现类似java中getClass()得到对象类名的方法
2015/07/27 Javascript
基于jquery实现的树形菜单效果代码
2015/09/06 Javascript
微信小程序 欢迎界面开发的实例详解
2016/11/30 Javascript
使用pm2自动化部署node项目的方法步骤
2019/01/28 Javascript
vue 通过绑定事件获取当前行的id操作
2020/07/27 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
2020/11/01 Javascript
[00:06]Yes,it worked!小卡尔成功穿越时空加入战场!
2019/07/20 DOTA
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
python使用PyV8执行javascript代码示例分享
2013/12/04 Python
Python引用传值概念与用法实例小结
2017/10/07 Python
Python实现可获取网易页面所有文本信息的网易网络爬虫功能示例
2018/01/15 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
学生信息管理系统Python面向对象版
2019/01/30 Python
python基于paramiko将文件上传到服务器代码实现
2019/07/08 Python
基于pytorch的lstm参数使用详解
2020/01/14 Python
Python如何发送与接收大型数组
2020/08/07 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
python实现KNN近邻算法
2020/12/30 Python
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
印度购买眼镜和太阳镜网站:Coolwinks
2018/09/26 全球购物
大专毕业生自我评价分享
2013/11/10 职场文书
工业设计专业自荐书
2014/06/05 职场文书
解除劳动合同协议书
2014/09/17 职场文书
实习班主任自我评价
2015/03/11 职场文书
2015员工年度考核评语
2015/03/25 职场文书
2015年化验室工作总结
2015/04/23 职场文书
2015年司法局工作总结
2015/05/22 职场文书
mysql5.5中文乱码问题解决的有用方法
2022/05/30 MySQL
Android实现获取短信验证码并自动填充
2023/05/21 Java/Android