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的商品展示放大镜
Aug 07 Javascript
基于jQuery的一个扩展form序列化到json对象
Dec 09 Javascript
基于javascript的JSON格式页面展示美化方法
Jul 02 Javascript
JavaScript表单焦点自动切换代码
Jul 24 Javascript
JS获取当前页面名称的简单实例
Aug 19 Javascript
使用jquery给新生的th绑定hover事件的实例
Feb 10 Javascript
微信小程序 首页制作简单实例
Apr 07 Javascript
捕获未处理的Promise错误方法
Oct 13 Javascript
利用vue和element-ui设置表格内容分页的实例
Mar 02 Javascript
node.js环境搭建图文详解
Sep 19 Javascript
layui table去掉右侧滑动条的实现方法
Sep 05 Javascript
vue2.0+SVG实现音乐播放圆形进度条组件
Sep 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
色色整理的PHP面试题集锦
2012/03/08 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
深入理解PHP+Mysql分布式事务与解决方案
2020/12/03 PHP
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
Javascript 运动中Offset的bug解决方案
2014/12/24 Javascript
jquery实现图片水平滚动效果代码分享
2015/08/26 Javascript
GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
2016/03/13 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
2016/10/26 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
Bootstrap下拉菜单样式
2017/02/07 Javascript
JS实现列表页面隔行变色效果
2017/03/25 Javascript
ES6新特性之变量和字符串用法示例
2017/04/01 Javascript
详解Vue组件之间的数据通信实例
2017/06/17 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
vue2.0 better-scroll 实现移动端滑动的示例代码
2018/01/25 Javascript
nuxt.js 缓存实践
2018/06/25 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
2018/09/08 Javascript
vue实现简单跑马灯效果
2020/05/25 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
微信小程序连续签到7天积分获得功能的示例代码
2020/08/20 Javascript
React实现轮播效果
2020/08/25 Javascript
python检测是文件还是目录的方法
2015/07/03 Python
Python 多进程和数据传递的理解
2017/10/09 Python
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
wxPython实现画图板
2020/08/27 Python
NumPy中的维度Axis详解
2019/11/26 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
海量信息软件测试笔试题
2015/08/08 面试题
大学四年规划书范文
2013/12/27 职场文书
投标承诺书范本
2014/03/27 职场文书
2014组织生活会方案
2014/05/19 职场文书
委托书的样本
2015/01/28 职场文书
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
2021/05/25 Vue.js
Nginx使用ngx_http_upstream_module实现负载均衡功能示例
2022/08/05 Servers