1. 前言

在之前的小节中我们介绍了 Vue 实例,本小节我们一起来了解一下 Vue 实例的生命周期。包括生命周期的几个阶段,以及各个阶段触发时机和作用。深入理解 Vue 的生命周期是本小节的难点,同学们不仅需要知道生命周期的执行顺序,还要理解各生命周期的作用。

2. 慕课解释

每个 Vue 实例在被创建时都要经过一系列的初始化过程 —— 例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。 — 官方定义

Vue 生命周期是指 Vue 实例对象从创建之初到销毁的整个过程。在生命周期的不同阶段 Vue 提供了不同的钩子函数,让用户可以在不同的阶段执行自己的代码。

3. 生命周期流程

我们来看一下官网给的 Vue 生命周期的图:
图片描述

从上面这幅图中,我们可以看到 vue 生命周期可以分为八个阶段,分别是:

  • beforeCreate(创建前)
  • created(创建后)
  • beforeMount (载入前)
  • mounted(载入后)
  • beforeUpdate(更新前)
  • updated(更新后)
  • beforeDestroy(销毁前)
  • destroyed(销毁后)

3.1 创建前(beforeCreate)

在实例初始化之后,此时的数据观察和事件机制都未形成,不能获得 DOM 节点。

3.2 创建后(created)

实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始。

3.3 载入前(beforeMount)

在挂载开始之前被调用:这个过程是在模版已经在内存中编译完成, render 函数首次被调用,此时完成了虚拟 DOM 的构建,但并未被渲染。

3.4 载入后(mounted)

这个过程在模版挂载之后被调用,页面完成渲染,所以在这之后,我们可以操作和访问 DOM 元素。

3.5 更新前(beforeUpdate)

当数据更新时调用,在这一阶段 DOM 会和更改过的内容同步。

3.6 更新后(updated)

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

3.7 销毁前(beforeDestroy)

实例销毁之前调用。在这一步,实例仍然完全可用。

3.8 销毁后(destroyed)

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

实例代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id = "app">
    {{ name }}
    <button @click="updateName">更新</button>
    <button @click="destroy">销毁</button>
  </div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type = "text/javascript">
  var vm = new Vue({
    el: '#app',
    data: {
      name:'hello !'
    },
    methods : {
      updateName() {
        console.log('准备修改名字啦!')
        this.name = 'hello 慕课!'
      },
      destroy(){
        vm.$destroy()
      }
    },
    beforeCreate() {
      // 此时页面数据未初始化
      console.log('beforeCreate:' + this.name) // beforeCreate: undefined
    },
    created() {
      // 页面数据已经初始化
      console.log('created:' + this.name) // beforeCreate: hello !
    },
    beforeMount() {
      console.log('beforeMount:' + this.name) // beforeCreate: hello !
    },
    mounted() {
      console.log('mounted:' + this.name) // beforeCreate: hello !
    },
    // 点击更新按钮后会先触发 beforeUpdate
    beforeUpdate() {
      console.log('beforeUpdate:' + this.name) // beforeCreate: hello 慕课!
    },
    updated() {
      console.log('updated:' + this.name) // updated hello 慕课 !
    },
    // 点击销毁按钮后会先触发 beforeDestroy
    beforeDestroy(){
      console.log('beforeDestroy: before destroy') // beforeDestroy: before destroy
    },
    destroyed(){
      console.log('destroyed: success') // destroyed: success
      // 在这之后点击页面 更新 按钮将无任何效果
    }
  });
</script>
</html>

4. 小结

本小节我们介绍了 Vue 的生命周期,了解了 Vue 从创建到销毁的一个过程。