vue 生命周期详解 (附代码)

时间:2024-10-07 09:46:11

一、 vue的生命周期是什么

vue每个组件都是独立的,都有自己的生命周期,从一个组件创建数据初始化挂载更新销毁,就是一个组件的生命周期。

一个组件首次加载时,也就只执行 创建、数据初始化到挂载。

生命周期给了用户在不同阶段添加自己的代码的机会

二、一个组件生命周期的全过程

首先得 new Vue() 实例化一个vue实例。

这时会执行初始化函数 :初始化生命周期函数 initLifecycle()、初始化事件 initEvent()、定义createElement函数 initRender()。

1. 执行 beforeCreated()

beforeCreated执行后,开始定义data数据、方法和事件,并完成数据劫持observe以及给组件实例配置watcher观察者实例。 这样当数据发生变化以后,才能感知数据的变化,完成页面的渲染。

2. 执行 created() ,此时已经可以拿到data和method下的方法 ,但是页面还没渲染出来

created执行后,如果没有实例对象el,会等待调用$mount(el),调用后$mount(el)后判断是否有template,如果有实例对象el,也会判断是否有template参数,拿到后template会转成render函数

3.执行 beforeMount()

beforeMount执行后,首先会产生一个虚拟dom,当render函数被渲染时就会产生真实的dom。真实的dom会替换掉原有的编译模板template,生成一个真正可用的HTML

4. 执行 mounted()  生命周期属性 _isMounted被置为true。另外我们是可以操作dom的,因为dom这时候已经渲染完成了

ok 到这了如果数据不变化的话,其实不用也不会执行beforeUpdate 和 update

5. 执行 beforeUpdate() 会重新生成一个新的虚拟dom,然后最拿这个最新的虚拟dom和原来的虚拟dom进行diff运算,从而更新render函数的最新数据,再将更新后的render重新渲染成真实dom,也就是数据更新

6. 执行 updated() ,这里可操作dom,并拿到最新一次更新的dom

ok 如果说vm.$destory()不被调用其实 beforeDestory 和 destory不用也不会执行

7. 执行 beforeDestory()  此时还能操作dom

beforeDestory执行后,会做一系列销毁,接触各种数据引用,移除事件监听,删除组件_watcher,删除子实例,删除自身self,同时将_isDestroyed设置为true

8. 执行 destory()  销毁已完成

ps:执行mounted和updated,不需要等所有的子组件都挂载完成,如果希望所有的视图都更新完后在做点什么事的话,最好在mounted和updated中加个$nextTick()。要做的事放在$nextTick()里

代码演示:

  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. <title>Document</title>
  7. <script src="/npm/vue@2.6.14/dist/"></script>
  8. </head>
  9. <body>
  10. <div id="app">
  11. <p>{{ message }}</p>
  12. <button @click="changeMessage">改变Message</button>
  13. </div>
  14. </body>
  15. <script>
  16. var app = new Vue({
  17. el: "#app",
  18. data: {
  19. message: "Hello Vue!"
  20. },
  21. methods: {
  22. changeMessage() {
  23. this.message = 'goodbye world'
  24. }
  25. },
  26. beforeCreate() {
  27. console.log("~~~~~~ 初始化前 ~~~~~~");
  28. console.log(this.message);
  29. console.log(this.$el);
  30. },
  31. created() {
  32. console.log("~~~~~~ 初始化完成 ~~~~~~");
  33. console.log(this.message);
  34. console.log(this.$el);
  35. },
  36. beforeMount() {
  37. console.log("~~~~~~ 挂载前 ~~~~~~");
  38. console.log(this.message);
  39. console.log(this.$el);
  40. },
  41. mounted() {
  42. console.log("~~~~~~ 挂载完成 ~~~~~~");
  43. console.log(this.message);
  44. console.log(this.$el);
  45. },
  46. beforeUpdate() {
  47. console.log("~~~~~~ 更新前 ~~~~~~");
  48. console.log(this.message);
  49. console.log(this.$el);
  50. },
  51. updated() {
  52. console.log("~~~~~~ 更新完成 ~~~~~~");
  53. console.log(this.message);
  54. console.log(this.$el);
  55. }
  56. });
  57. </script>
  58. </html>

控制台打印截图(可以暂时注释methods 代码,即能看到截图效果)

可以看到,首次加载,只经历了创建前后、挂载前后 4个生命周期。

另外挂载前我们看到的el 其实还是模板template 到挂载完成就渲染成真实的dom并替换了原来的模板。

 

参考学习:

超详细vue生命周期解析(详解)_ら陈佚晨的博客-****博客_vue生命周期

     谈谈vue生命周期-看了这篇你就懂了 - 简书