博客列表 >07-Vue_生命周期钩子

07-Vue_生命周期钩子

 一纸荒凉* Armani
 一纸荒凉* Armani原创
2021年05月06日 11:42:03815浏览

vue实例的生命周期

  • 什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
  • 生命周期钩子:就是生命周期事件的别名而已;
  • 生命周期钩子 = 生命周期函数 = 生命周期事件

这张图对于Vue的生命周期和钩子函数说的非常的明白。下面我们看一张关于Vue生命周期中出现的钩子函数示意图。

Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

Vue应用程序中有4个主要事件(8个主要钩子)。主要的生命周期函数分类:

  • 创建 — 在组件创建时执行
  • 挂载 — DOM 被挂载时执行
  • 更新 — 当响应数据被修改时执行
  • 销毁 — 在元素被销毁之前立即运行

创建期间的生命周期函数:

  • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
  • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板

挂载期间的生命周期函数:

  • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
  • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示

更新期间的生命周期函数:

  • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
  • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!

销毁期间的生命周期函数:

  • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
  • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>生命周期全过程</title>
  5. <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
  6. </head>
  7. <body>
  8. <div id="app">
  9. <p>{{ message }}</p>
  10. </div>
  11. <script type="text/javascript">
  12. var app = new Vue({
  13. el: '#app',
  14. data: {
  15. message : "hello world!"
  16. },
  17. beforeCreate: function () {
  18. console.group('beforeCreate 创建前状态===============》');
  19. console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
  20. console.log("%c%s", "color:red","data : " + this.$data); //undefined
  21. console.log("%c%s", "color:red","message: " + this.message) //undefined
  22. },
  23. created: function () {
  24. console.group('created 创建完毕状态===============》');
  25. console.log("%c%s", "color:red","el : " + this.$el); //undefined
  26. console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
  27. console.log("%c%s", "color:red","message: " + this.message); //已被初始化
  28. },
  29. beforeMount: function () {
  30. console.group('beforeMount 挂载前状态===============》');
  31. console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化
  32. console.log(this.$el);
  33. console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
  34. console.log("%c%s", "color:red","message: " + this.message); //已被初始化
  35. },
  36. mounted: function () {
  37. console.group('mounted 挂载结束状态===============》');
  38. console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
  39. console.log(this.$el);
  40. console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
  41. console.log("%c%s", "color:red","message: " + this.message); //已被初始化
  42. },
  43. beforeUpdate: function () {
  44. console.group('beforeUpdate 更新前状态===============》');
  45. console.log("%c%s", "color:red","el : " + this.$el);
  46. console.log(document.querySelector('#app').innerHTML);
  47. console.log("%c%s", "color:red","data : " + this.$data);
  48. console.log("%c%s", "color:red","message: " + this.message);
  49. },
  50. updated: function () {
  51. console.group('updated 更新完成状态===============》');
  52. console.log("%c%s", "color:red","el : " + this.$el);
  53. console.log(document.querySelector('#app').innerHTML);
  54. console.log("%c%s", "color:red","data : " + this.$data);
  55. console.log("%c%s", "color:red","message: " + this.message);
  56. },
  57. beforeDestroy: function () {
  58. console.group('beforeDestroy 销毁前状态===============》');
  59. console.log("%c%s", "color:red","el : " + this.$el);
  60. console.log(this.$el);
  61. console.log("%c%s", "color:red","data : " + this.$data);
  62. console.log("%c%s", "color:red","message: " + this.message);
  63. },
  64. destroyed: function () {
  65. console.group('destroyed 销毁完成状态===============》');
  66. console.log("%c%s", "color:red","el : " + this.$el);
  67. console.log(this.$el);
  68. console.log("%c%s", "color:red","data : " + this.$data);
  69. console.log("%c%s", "color:red","message: " + this.message)
  70. }
  71. })
  72. </script>
  73. </body>
  74. </html>

每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁。

  1. 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
  2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  3. 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…
  5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
  6. 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
  7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
  8. 组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>完整的生命周期</title>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <my-template></my-template>
  12. </div>
  13. <template id="myTemplate">
  14. <div>
  15. <p class="myp">A组件</p>
  16. <button @click="destroy">destroy</button>
  17. <input type="text" v-model="msg">
  18. <p>msg:{{msg}}</p>
  19. </div>
  20. </template>
  21. </body>
  22. <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
  23. <script>
  24. //生命周期:初始化阶段 运行中阶段 销毁阶段
  25. Vue.component("myTemplate",{
  26. template:"#myTemplate",
  27. data:function(){
  28. return {msg:'hello'}
  29. },
  30. timer:null,
  31. methods:{
  32. destroy:function(){
  33. this.$destroy(); // 断点 销毁组件
  34. }
  35. },
  36. beforeCreate:function(){
  37. console.group('beforeCreate 创建前状态===============》');
  38. console.log('beforeCreate:刚刚new Vue()之后,这个时候,数据还没有挂载呢,只是一个空壳')
  39. console.log(this.msg)//undefined
  40. console.log(document.getElementsByClassName("myp")[0])//undefined
  41. },
  42. created:function(){
  43. console.group('created 创建完毕状态===============》');
  44. console.log('created:这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数')
  45. this.msg+='!!!'
  46. console.log('在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取')
  47. console.log('接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染')
  48. },
  49. beforeMount:function(){
  50. console.group('beforeMount 挂载前状态===============》');
  51. console.log('beforeMount:虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated')
  52. this.msg+='@@@@';
  53. console.log('在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取')
  54. console.log(document.getElementsByClassName("myp")[0])//undefined
  55. console.log('接下来开始render,渲染出真实dom')
  56. },
  57. // render:function(createElement){
  58. // console.log('render')
  59. // return createElement('div','hahaha')
  60. // },
  61. mounted:function(){
  62. console.group('beforeMount 挂载结束状态===============》');
  63. console.log('mounted:此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了')
  64. console.log(document.getElementsByClassName("myp")[0])
  65. console.log('可以在这里操作真实dom等事情...')
  66. // this.$options.timer = setInterval(function () {
  67. // console.log('setInterval')
  68. // this.msg+='!'
  69. // }.bind(this),500)
  70. },
  71. beforeUpdate:function(){
  72. console.group('updated 更新前状态===============》');
  73. //这里不能更改数据,否则会陷入死循环
  74. console.log('beforeUpdate:重新渲染之前触发')
  75. console.log('然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染')
  76. },
  77. updated:function(){
  78. console.group('updated 更新完成状态===============》');
  79. //这里不能更改数据,否则会陷入死循环
  80. console.log('updated:数据已经更改完成,dom也重新render完成')
  81. },
  82. beforeDestroy:function(){
  83. console.group('destroyed 销毁前状态===============》');
  84. console.log('beforeDestory:销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等...')
  85. // clearInterval(this.$options.timer)
  86. },
  87. destroyed:function(){
  88. console.group('destroyed 销毁完成状态===============》');
  89. console.log('destroyed:组件的数据绑定、监听...都去掉了,只剩下dom空壳,这里也可以善后')
  90. }
  91. })
  92. const vm = new Vue({
  93. }).$mount('#app')
  94. </script>
  95. </html>

生命周期总结

这么多钩子函数,我们怎么用呢,我想大家可能有这样的疑问吧,我也有,哈哈哈。

  • beforecreate : 举个栗子:可以在这加个loading事件
  • created :在这结束loading,还做一些初始化,实现函数自执行
  • mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些事情
  • beforeDestory: 你确认删除XX吗?
  • destoryed :当前组件已被删除,清空相关内容
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议