Vue实例生命周期

1,098 阅读4分钟

首先说明:keep-alive组件定制的钩子,activated和deactivated 暂不讨论,本文以说明下图中的生命周期为主

什么是生命周期

  • 从Vue实例创建,运行,到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期

生命周期钩子

  • 生命周期事件的别名

主要的生命周期函数:

  • 创建期间的生命周期函数:
    • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好data和methods属性
    • created:实例已经在内存中创建好,此时,data和methods已经创建好,但是还没有开始编译模板
    • beforeMount:此时已将完成了模板的编译,但是还没有挂载到页面中去
    • mounted:此时,已经将编译好的模板挂载到了页面指定的容器中显示
  • 运行期间的生命周期函数:
    • beforeUpdate:状态更新之前执行的函数,此时data中的状态是最新的,但是页面上显示的数据还是旧的,因为此时还没有重新渲染DOM节点
    • updated:实例更新完毕之后调用此函数,此时data中的状态值和页面上显示的数据,都已经完成了更新,页面已经被重新渲染好了
  • 销毁期间的生命周期函数:
    • beforeDestory:实例销毁之前带调用的函数,在这一步,实例仍然完全可用
    • destoryed: Vue实例销毁之后调用,调用后,Vue实例所有绑定都会解绑,所有事件监听器都会被移除,所有的子实例也会被销毁

另外:

  • 由于beforeUpdate和updated这两个周期函数是在运行阶段的函数,只有data数据变化时才会被执行,所以执行次数最少为0次,最多为无数次

代码说明

  • 模板部分
<div id="app">
    <h3 id="h3">{{msg}}</h3>
    // button用来触发data数据更新
    <button @click="msg='update'">修改msg</button>
  </div>
  • Vue实例部分
var vm = new Vue({
    el: '#app',
    data: {
        msg: 'Vue'
    },
    
      // 在beforeCreate生命周期函数执行时,data和methods中的数据都还没有被初始化
      beforeCreate() {
        // 输出为:undefined
        console.log(this.msg +' beforeCreate') 
        // 输出为:Error in beforeCreate hook: "TypeError: this.show is not a function"
         this.run() 
      },
      
      // 在created生命周期函数执行时, data和methods都已经初始化完成
      // 所以想要调用methods中的方法或者操作data中的数据,最早只能在created函数中
      created() {
        // console.log(this.msg + ' creaated') // 输出为:Vue
        // this.run() // run函数已经被执行
      },
      // 在created之后Vue开始编译模板(会判断存在的模板属性是el还是template),执行Vue代码中的指令
      // 然后会在内存中生成一个编译好的模板字符串,并在内存中生成DOM,但此时只是在内存中,并未真正挂载到页面上
      
      // 在beforeMount生命周期函数执行时,模板已经在内存中编辑完成了,但是还没有被挂载到页面上
      // 在此时,页面中的元素还没有真正的将数据替换进去,只是存在内存中的模板字符串
      beforeMount() {
        // 输出为:{{msg}}
        console.log(document.getElementById('h3').innerHTML)
      },
      
      // 在mouted生命周期函数执行时,内存中已经编译好的模板,被取出挂载到页面上,DOM被渲染完成
      // 所以mounted是可对DOM进行操作的最早阶段
      // 此时Vue实例已经完全被创建好了,在此之后Vue将进入运行阶段
      mounted() {
        // 输出为:Vue
        console.log(document.getElementById('h3').innerHTML)
      },
      
      // 在此时beforeUpdate生命周期函数执行,页面还没有被更新,数据已经被改变了
      beforeUpdate() {
        // 此时通过触发button修改msg为update
        // 输出为:Vue
        console.log(document.getElementById('h3').innerHTML)
        // 输出为:update
        console.log(this.msg + ' beforeUpdate')
        // 此时获取的DOM元素中的显示数据为Vue,而正是data中的数据已经被改为update
      },
      
      // 在update生命周期函数执行时,页面和data数据已经全都更新
      updated() {
        // 输出为:update
        console.log(document.getElementById('h3').innerHTML)
        // 输出为:update
        console.log(this.msg + 'updated')
      },
      
       // 在beforeDestory生命周期函数执行时,实例已经进入销毁阶段
      // 此时实例上所有的data和methods,指令,过滤器等都是可用的,实例还未真正开始销毁
      beforeDestory() {
          
      },
      
      // 在destory生命周期函数执行时,实例已经被完全销毁了
      // 此时实例上所有的data和methods,指令,过滤器等都是不可用的
      destory() {
          
      },
      
    methods: {
        run() {
          console.log('run函数已经被执行') 
        }
    }
})

此外Vue还存在一种生命周期函数: errorCaptured

  • 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播
  • 可以在此钩子中修改组件的状态。因此在模板或渲染函数中设置其它内容的短路条件非常重要,它可以防止当一个错误被捕获时该组件进入一个无限的渲染循环。