vue2 vue3生命周期

3,980 阅读3分钟

今天也有很努力的在赚猫粮钱

如若文章存在错误或不足,望理解并帮我指出,感激不尽


一个完整的vue生命周期会经历以下钩子函数

4个阶段(可以理解为一个组件的生、老、病、死),8个钩子函数

beforeCreate --- 创建前

created --- 创建完成

beforeMount --- 挂载前

mounted --- 挂载完成

beforeUpdate --- 更新前

updated --- 更新完成

beforeDestroy --- 销毁前

destroyed --- 销毁完成

image.png


beforeCreate是new Vue()之后触发的第一个钩子,一个组件生命的开始,当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。

created阶段实例已经创建完成,已经完成了数据观测, 可以使用数据,更改数据,在这里更改数据不会触发updated函数。

结合代码看一下吧

  • HTML
<template>
 <div id="app">
    <h1 ref="hello" id="hello">{{message}}</h1>
    <button @click="changeMsg">change</button>
 </div>
</template>
  • DATA
  data () {
    return {
      message: '娟娟和她的三只小猫咪'
    }
  },
  • js
    beforeCreate: function() {
      console.group('------beforeCreat 创建前------');
      console.log("%c%s", "color: green","data   : " + this.$data); 
      console.log("%c%s", "color: green","message: " + this.message);  
    },
    created: function() {
      console.group('------created 创建完成------');
      console.log("%c%s", "color: green","data   : " + this.$data); 
      console.log("%c%s", "color: green","message: " + this.message);  
      let hello = document.getElementById('hello')
      console.log('hello:',hello)
    },

看看控制台的打印结果,是不是很直观

image.png


image.png


beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。

mounted在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

结合代码看一下吧

      beforeMount: function() {
      console.group('------beforeMount 挂载前------');
      console.log(this.$el);
      console.log("%c%s", "color:green","data   : " + this.$data); //已被初始化  
      console.log("%c%s", "color:green","message: " + this.message); //已被初始化  
      let hello = document.getElementById('hello')
      console.log('hello:',hello)
    },
      mounted: function() {
      console.group('------mounted 挂载完成------');
      console.log(this.$el);
      console.log("%c%s", "color:green","data   : " + this.$data); 
      console.log("%c%s", "color:green","message: " + this.message); 
      let hello = document.getElementById('hello')
      console.log('hello:',hello)
    },

image.png


image.png


beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器,可能导致内存泄漏,变量污染的一些变量,方法等

destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也被销毁。


如果使用组件的keep-alive功能时,增加两个周期:

activatedkeep-alive组件激活时调用;

deactivatedkeep-alive组件停用时调用。

<keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。<keep-alive>是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件链中。 当在<keep-alive>内切换组件时,它的activateddeactivated这两个生命周期钩子函数将会执行。


既然生命周期讲了这么多顺便讲一些vue3中生命生命周期的变化

vue3.x生命周期变化

image.png

被替换

  • beforeCreate -> setup()

  • created -> setup()

重命名

  • beforeMount -> onBeforeMount

  • mounted -> onMounted

  • beforeUpdate -> onBeforeUpdate

  • updated -> onUpdated

  • beforeDestroy -> onBeforeUnmount

  • destroyed -> onUnmounted

  • errorCaptured -> onErrorCaptured

新增的

新增的以下2个方便调试 debug 的回调钩子:

  • onRenderTracked

  • onRenderTriggered

可以查看官方api

特别说明 在 Vue3.x 是兼容 Vue2.x 的语法的,因此 Vue2.x 的语法能正常在 Vue3.x 中运行,比如:虽然 beforeCreate 、 created 被 setup() 函数替代了,但是如果你要用,代码也是正常执行的。只是在 Vue3.x 中建议使用 setup(),而不是旧的API,但是,以下2个生命周期钩子函数被改名后,在 Vue3.x 中将不会再有 beforeDestroy 和 destroyed

  • beforeDestroy -> onBeforeUnmount

  • destroyed -> onUnmounted


深入理解生命周期,比如说API请求一般会放在哪个阶段,各个阶段data,method,dom的区别,各阶段的特殊所在。切忌盲目背完8个生命钩子。