详解 Vue2 组件生命周期

Wu-JunHui大约 9 分钟VueVue2组件生命周期生命周期钩子

详解 Vue2 组件生命周期

概述

在 Vue 中,一个组件本质上是一个拥有预定义选项的 Vue 实例对象,而组件生命周期(Life Cycle),就是指一个 Vue 实例被创建、运行、销毁的整个阶段

生命周期函数

也称为生命周期钩子,是 Vue 提供的内置函数,会伴随着 Vue 实例的生命周期,自动按次序执行,强调的是一个时间点

函数种类

每个 Vue 实例在被创建时都要经过一系列的初始化过程,例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等

与此同时,Vue 会在 Vue 实例创建、运行、销毁各阶段执行不同的生命周期钩子,使得开发者可在不同阶段针对需求调用不同的生命周期钩子

Vue2 组件的生命周期中,可调用的 8 个生命周期钩子:

Vue2生命周期钩子
Vue2生命周期钩子

函数使用

在 Vue2 中,生命周期钩子是直接作为选项被调用,即与 data 选项平级,函数内部的 this 指向调用它的 Vue 实例/组件实例

<script>
export default {
  created: function () {
    // this指向当前组件实例
  },

  // ES6对象方法简写形式
  created() {
    // this指向当前组件实例
  }
}
</script>

提示

  1. 无论开发者是否有调用,所有生命周期钩子都会按组件生命周期的顺序自动被执行

  2. 生命周期钩子,或所有函数形式的选项式 API,不能使用箭头函数,因为它内部没有 this 对象,若在箭头函数中使用 this,它将作为变量一直向上级词法作用域查找直至找到为止,否则可能会报无法读取 undefined 的属性等错误

  3. Vue2 还提供了 4 个与生命周期相关的实例方法,参考 Vue2 官方 APIopen in new window

详解生命周期

在了解完生命周期钩子后,接下来将以一个组件实例的创建、运行、销毁的过程(在内存中很快完成),详细分析 Vue2 的 Vue 实例生命周期(一个组件实例本质上是一个拥有预定义选项的 Vue 实例)

提示

生命周期图示类似于程序流程图open in new window,其中箭头表示控制流,矩形表示加工步骤(起始框、执行框),菱形表示逻辑条件(判断框)

一、组件创建阶段

1. new Vue()

该步骤旨在创建一个 Vue 实例,在不同情况下,创建 Vue 实例有着不同的方法:

  • Vue.js 最基础的用法中,是直接在 HTML 文件中,通过 new 关键字来调用 Vue.js 提供的 Vue 构造函数以创建 Vue 实例,然后使用 Vue 提供的选项式 API来协助渲染当前 HTML 文件的结构、行为、样式
    此用法并未涉及到组件系统,但本质上已经在使用组件来定义页面 UI 结构,组件在该用法中是通过包含 Vue 选项式 APIJavaScript 对象来定义的,并未使用 .vue 文件

  • 在 Vue 项目或使用构建工具中,则是使用 .vue 文件来定义组件
    Vue 项目接入组件系统:在 main.js 中创建 Vue 实例并设置 DOM 挂载点后,通过渲染函数解析 .vue 文件:

    • 将页面结构交由组件 template 标签定义
    • 页面行为交由组件 script 标签定义
    • 页面样式由组件 style 标签定义

    通过组件嵌套进一步完善页面的 UI 结构,此时原本的 HTML 文件更像是组件系统的出口文件,而根组件则是其他组件的入口文件

.vue 文件可近似理解为构造函数,在通过标签形式使用组件时,相当于 new 构造函数以创建一个组件实例

2. Init Events & Lifecycle

在创建出 Vue 实例后,Vue 就会在内存中初始化此组件实例的事件以及生命周期函数

3. beforeCreate

当上一步事件与生命周期函数初始化完成后,beforeCreate 函数就会被自动执行

阶段状态

此阶段组件实例的 props/data/methods尚未创建,处于不可用状态,因此 beforeCreate 函数在实际开发中用处不大

4. Init Injections & Reactivity

beforeCreate 函数执行完毕后,开始初始化组件实例的 props/data/methods

5. created

当上一步组件实例的注入与校验初始化完成后,created 函数就会被自动执行

阶段状态

  1. 组件实例的 props/data/methods 均已创建好,处于可用状态
  2. 组件实例的模板结构 template 尚未生成
  3. created 函数十分重要,它是生命周期中最早能发起 Ajax 请求的函数

6. 编译 HTML 结构

created 函数执行完毕后,则需要开始编译 HTML 结构,需按顺序进行一系列的条件判断

(1)判断 el 选项是否存在:

存在:即 Vue 实例设置了 el 选项,则直接进入下一步:判断 template 选项是否存在
不存在:则等待 Vue 实例 调用 $mount() 方法后,再进入 template 选项判断框,否则将报错

(2)判断 template 选项是否存在:

存在:将 template 选项定义的模板结构,编译到 render 函数中传入的参数所控制的区域
不存在:Vue 会根据组件实例中的 template 部分编译 el 选项所控制区域的 HTML 结构,此 HTML 结构可称为 outerHTML

outerHTML

表示外层 HTML,是因为所编译的 HTML 来源于组件的 template,而不是 el 选项所控制区域内部本身的 HTML 结构

(3)开始编译

当执行完上两步的判断后,开始基于数据和模板,在内存中编译生成页面的 HTML 结构,编译的工作由依赖包中的 vue-template-compiler 完成

7. beforeMount

当页面 HTML 结构编译完成后,beforeMount 函数就会被自动执行

阶段状态

  1. 内存中已编译好 HTML 结构,但未渲染到浏览器中,此时浏览器中还没有当前组件的 DOM 结构
  2. 此生命周期钩子同样可以发起 Ajax 请求,但在 created 函数中能更早地拿到数据,因此它在实际开发中用处不大

8. 创建 vm.$el 并替换 el 选项

beforeMount 函数执行完毕后,紧接着:

(1)用内存中编译生成的 HTML 结构,替换el 选项指定的 DOM 元素
(2)同时创建 Vue 实例属性 vm.$el,表示 Vue 实例使用的根 DOM 元素

阶段状态

此执行框结束后,组件中的 DOM 结构就已经被渲染到浏览器

9. mounted

el 选项指定的 DOM 被组件模板结构替换且 vm.$el 创建后,mounted 函数就会被自动执行

阶段状态

此时浏览器已包含了当前组件的 DOM 结构,该生命周期钩子是最早可操作到组件中的 DOM 元素的,在实际开发中十分重要

10. Mounted

进入 Mounted 阶段,表示组件实例已挂载完毕,已成功创建并渲染到浏览器中

小结:组件创建阶段图解

Vue2组件创建阶段
Vue2组件创建阶段

二、组件运行阶段

组件在内存中的创建阶段结束后,就进入组件的运行阶段

1. beforeUpdate

当组件实例中的任何数据(如 data 选项、computed 选项)发生变化时,beforeUpdate 函数就会被自动执行

阶段状态

此阶段的数据已被更新,但相应的 DOM 结构未重新渲染

2. 重新渲染虚拟 DOM

beforeUpdate 生命周期钩子执行完毕后,将根据最新的数据,重新渲染组件的虚拟 DOM,并将更新应用到真实的 DOM 中

3. updated

当 DOM 重新渲染完毕后,updated 函数就会被自动执行

此阶段表示 Vue 已根据最新的数据,完成了组件 DOM 结构的重新渲染

操作最新 DOM

当数据变化后,为了能够操作到最新的 DOM 结构,将逻辑代码写到 updated 函数虽是可行的,但该生命周期钩子会在每次数据变化时都会被执行一次
作为补充,Vue 提供了实例方法 vm.$nextTick() ,它表示将在 DOM 更新完毕后调用回调,参考 vm.$nextTickopen in new window

4. Mounted

更新完毕后再次进入 Mounted 阶段,等待下一次数据更新或进行销毁

小结

整个重渲染过程最少执行 0 次,即数据一直没有发生任何变化,最多执行无限次

组件运行阶段图解:

Vue2组件运行阶段
Vue2组件运行阶段

三、组件销毁阶段

当调用了实例方法 vm.$destroy() 方法后,将进入组件销毁阶段:

1. beforeDestroy

调用实例方法 vm.$destroy() 后,beforeDestroy 函数就会被自动执行,此时尚未销毁组件,组件还处于正常工作状态

2. 销毁组件

beforeDestroy 函数执行完毕后,将真正进入组件销毁阶段:

销毁组件的侦听器子组件以及事件监听函数

3. Destroyed

此阶段表示组件已被销毁,此组件在浏览器中对应的 DOM 结构已被完全移除

4. destroyed

当组件完全销毁后,destroyed 函数就会被自动执行

小结:组件销毁阶段图解

Vue2组件销毁阶段
Vue2组件销毁阶段

四、完整图解

总结

生命周期强调的是时间段生命周期函数强调的是时间点

整个生命周期中,最重要的是 createdmountedupdated 3 个函数

参考

Vue2 生命周期open in new window
Vue2 生命周期钩子open in new window

上次编辑于:
贡献者: Wu-JunHui
Loading...