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 相关文章推荐
JavaScript 原型与继承说明
Jun 09 Javascript
js格式化时间小结
Nov 03 Javascript
JavaScript实现横向滑出的多级菜单效果
Oct 09 Javascript
基于jQuery实现点击弹出层实例代码
Jan 01 Javascript
深入浅析JavaScript面向对象和原型函数
Feb 06 Javascript
基于Bootstrap实现tab标签切换效果
Apr 15 Javascript
在Swiper内如何制作CSS3动画效果示例代码
Dec 07 Javascript
详解ajax的data参数错误导致页面崩溃
Apr 30 Javascript
vue+element 模态框表格形式的可编辑表单实现
Jun 07 Javascript
JavaScript箭头函数中的this详解
Jun 19 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
Mar 09 Javascript
vue中的.$mount('#app')手动挂载操作
Sep 02 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简单计算页面加载时间的方法
2015/06/19 PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
2017/08/10 PHP
JavaScript 学习技巧
2010/02/17 Javascript
JS关键字球状旋转效果的实例代码
2013/11/29 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
js精美的幻灯片画集特效代码分享
2015/08/29 Javascript
AngularJs实现ng1.3+表单验证
2015/12/10 Javascript
bootstrap实现弹窗和拖动效果
2016/01/03 Javascript
个人网站留言页面(前端jQuery编写、后台php读写MySQL)
2016/05/03 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
js 获取经纬度的实现方法
2016/06/20 Javascript
Bootstrap CDN和本地化环境搭建
2016/10/26 Javascript
Vue.js实现无限加载与分页功能开发
2016/11/03 Javascript
实例讲解DataTables固定表格宽度(设置横向滚动条)
2017/07/11 Javascript
JavaScript中防止微信浏览器被整体拖动的方法
2017/08/25 Javascript
node内置调试方法总结
2018/02/22 Javascript
微信小程序页面间传递数组对象方法解析
2019/11/06 Javascript
[01:09:01]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第一场 10.28
2020/10/28 DOTA
python中查找excel某一列的重复数据 剔除之后打印
2013/02/10 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
Django使用中间件解决前后端同源策略问题
2019/09/02 Python
python生成随机红包的实例写法
2019/09/02 Python
基于Python实现剪切板实时监控方法解析
2019/09/11 Python
python闭包、深浅拷贝、垃圾回收、with语句知识点汇总
2020/03/11 Python
Python模块zipfile原理及使用方法详解
2020/08/04 Python
利物浦足球俱乐部官方网上商店:Liverpool FC Official Store
2018/01/13 全球购物
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
法国在线药房:1001Pharmacies
2021/03/07 全球购物
档案接收函
2014/01/13 职场文书
本科应届生自荐信
2014/06/29 职场文书
合作协议书格式
2014/08/19 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
化验员岗位职责
2015/02/14 职场文书
vue引入Excel表格插件的方法
2021/04/28 Vue.js
python中的None与NULL用法说明
2021/05/25 Python
 Redis 串行生成顺序编码的方法实现
2022/04/03 Redis