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中的变量使用说明
May 18 Javascript
Jquery CheckBox全选方法代码附js checkbox全选反选代码
Jun 09 Javascript
jquery $.each()使用探讨
Sep 23 Javascript
js查找某元素中的所有图片地址的方法
Jan 16 Javascript
深入理解javascript变量声明
Nov 20 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
使用JavaScript实现连续滚动字幕效果的方法
Jul 07 Javascript
JS+CSS实现的简单折叠展开多级菜单效果
Sep 12 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
Feb 14 Javascript
Router解决跨模块下的页面跳转示例
Jan 11 Javascript
基于layui数据表格以及传数据的方式
Aug 19 Javascript
解决element ui select下拉框不回显数据问题的解决
Feb 20 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第一次无法获取cookie问题处理
2014/12/15 PHP
PHP把MSSQL数据导入到MYSQL的方法
2014/12/27 PHP
centos下file_put_contents()无法写入文件的原因及解决方法
2017/04/01 PHP
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
js变换显示图片的实例
2013/04/16 Javascript
JavaScript父子窗体间的调用方法
2015/03/31 Javascript
jquery+json实现数据二级联动的方法
2015/11/28 Javascript
浅谈js数据类型判断与数组判断
2016/08/29 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
2017/01/03 Javascript
妙用Angularjs实现表格按指定列排序
2017/06/23 Javascript
electron中使用bootstrap的示例代码
2018/11/06 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
微信小程序视图控件与bindtap之间的问题的解决
2019/04/08 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
ES6中let、const的区别及变量的解构赋值操作方法实例分析
2019/10/15 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
纯js+css实现在线时钟
2020/08/18 Javascript
Vue 列表页带参数进详情页的操作(router-link)
2020/11/13 Javascript
使用Python编写提取日志中的中文的脚本的方法
2015/04/30 Python
简介Django框架中可使用的各类缓存
2015/07/23 Python
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
python编程线性回归代码示例
2017/12/07 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
pycharm使用matplotlib.pyplot不显示图形的解决方法
2018/10/28 Python
pytorch 实现查看网络中的参数
2020/01/06 Python
pytorch:实现简单的GAN示例(MNIST数据集)
2020/01/10 Python
HTML5 本地存储之如果没有数据库究竟会怎样
2013/04/25 HTML / CSS
美国CVS药店官网:CVS Pharmacy
2018/07/26 全球购物
大学系主任推荐信范文
2013/12/24 职场文书
《苏珊的帽子》教学反思
2014/04/07 职场文书
个人汇报材料范文
2014/12/30 职场文书
管理人员岗位职责
2015/02/14 职场文书
酒店收银员岗位职责
2015/04/07 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
2015年母亲节活动策划方案
2015/05/04 职场文书
JavaWeb实现显示mysql数据库数据
2022/03/19 Java/Android