Vue2 和 Vue3 生命周期详解

2,189 阅读2分钟

Vue实例和组件都会经历从初始化创建到销毁的完整过程,这个过程叫生命周期,同时在这个过程中会运行一些叫生命周期钩子的函数

Vue2 生命周期

lifecycle.png

new Vue()

新建vue实例

Init Events & Lifecycle

初始化内部事件(on once off emit
初始化生命周期方法(mount nextTick forceUpdate destory)和钩子(不然之后的beforeCreate都没法执行)

生命周期方法和内部事件的使用示例:

methods: {
    handleClick() {
        this.$emit('popupChange', { xx: true })
        this.$nextTick(() => {}) // 视图更新后
    }
}

beforeCreate

实例创建前 在数据监测等还没开始前
可以拿到this.$route.name的值

Init injections & reactivity

injections 通过依赖注入导入依赖项(provide injec 将父组件provide中的对象注入到子组件的属性中) reactivity 将data里的数据变成响应式的

created

实例创建完成
完成数据观测、属性 方法(props methods)的初始化 可以访问属性 打印方法 但拿不到this.$el以及DOM元素的引用 (vue3的setup函数已经替代了这两个生命周期钩子)

判断实例上有没el项

判断当new Vue({...})里的option 如果没有el项 就等到手动调用vm.$mount(),否则直接检查是否有template项 有就编并填充template项所绑定的区域 并进入render 没有就编译并替换el项的outerHtml(整个<div id="app">...</div>)区域

new Vue({
    el: '#app', // el项
    router,
    store,
    render: h => h(App)
})

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

beforeMounted

挂载前,el已经创建完成 但还没挂载到实例上

mounted

挂载后,此时el已经被this.$el替换了 并挂载到实例之后,视图dom已经初始化完毕 在这里可进行一些手动的dom操作,一般的我也会在这里进行ajax请求

beforeUpdate

数据data更新后 视图即将渲染之前

update

组件重新渲染完毕后 不建议在这两个钩子里做任何操作 容易造成死循环!

beforeDestroyed
destroyed

在组件实例销毁之后调用(比如关闭页面、路由切换,但刷新页面不会) 或手动调用this.$destory()时

errorCaptured

Vue 2.5.0+ 新增的
当捕获一个来自子组件的错误时被调用,钩子函数收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串,此钩子可以返回false以阻止该错误继续向上传播

actived
deactived

当使用了内置的 keep-alive 来包裹组件 来实现缓存组件实例时(保存组件的渲染状态)activeddeactived 就对应实例 激活失效

Vue3 生命周期

Vue3 通过 Composition API 模块化的方式引入 生命周期 Hooks。组合式API写法比较自由方便,尤其放在 <script setup>
这里 setup 函数阶段替代了旧的 beforeCreatecreated,其他 Hooks 必须在 setup 内部调用

import { defineComponent, onMounted } from 'vue'
export default defineComponent({
  name: 'xxx',
  setup() {
    onMounted(() => {
      console.log('在组件完成初始渲染 并创建 DOM 节点后')
    })
  }
})

Options API 对应的 Vue3 Composition API 生命周期 Hooks

  • beforeCreate -> setup
  • created -> setup
  • beforeMount -> onBeforeMount
  • mounted -> ****
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

<keep-alive />

  • activated -> onActivated
  • deactivated -> onDeactivated

另外 Vue3 中新增了:

onRenderTracked(只能在开发环境调试使用)
状态跟踪,它会跟踪页面上所有响应式变量和方法的状态(setup函数return返回的值)页面只要有update,它就会跟踪,然后生成一个event对象,通过event对象 我们可以查找程序的问题所在

onRenderTriggered(只能在开发环境调试使用)
状态触发,它不会跟踪每一个值,而是给出变化值的信息,并且新值和旧值都会明确的展示出来,它只跟着发生变化的值,这样我么吧可以对程序进行精准的调试

Vue3 的生命周期图示:

lifecycle.png