Vue的生命周期钩子

374 阅读2分钟

简介及理解

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

生命周期函数就是vue实例在某一时间点会自动执行的函数。

顾名思义,生命周期可以类比为受精卵的发育过程,从受精卵到桑葚胚、囊胚,不同的分裂阶段基因会指导进行不同的分裂分化。同理,生命周期钩子函数就是在实例创建、更新、销毁过程中,通过不同的钩子函数,做到在Vue实例自然的生命过程中进行干预。

生命周期钩子函数

钩子函数属于实例,并不放在methods内,使用时:

var vm = new Vue({
    el:"#app",
    data:{
    ...
    }
    beforeCreate:function(){
        console.log("111");
    }
})

beforeCreate

  • 类型:Function

  • 详细: 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

  • 页面调用之前执行

 beforeCreate:function() {
    alert('beforCreate hook has been called');
    console.log('beforCreate hook has been called');
  }

created

  • 类型:Function

  • 详细: 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性(获取Vue实例关联的DOM元素)目前尚不可用。

  • 创建完成后执行,可以取出变量的数据类型,这在上一个生命期内不行。但是 Vue 实例在此阶段尚未安装,因此你无法在此处操作 DOM,元素属性尚不可用。

beforeMount

  • 类型:Function

  • 详细: 在挂载开始之前被调用:相关的 render 函数首次被调用。

      该钩子在服务器端渲染期间不被调用。

  • 挂载前执行模板和作用域样式都在这里编译,但是你仍然无法操作DOM、元素属性仍然不可用,只能做到根据id获取位置,但不能显示内置内容

mounted

  • 类型:Function

  • 详细: 实例被挂载后调用,这时 el 被新创建的 vm.$el 替换。 如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm.$el也在文档内。

  • 在安装实例后会立即调用它。现在 app 组件或项目中的其他组件都可以使用了。现在可以进行数据适合模板、DOM元素替换为数据填充元素之类的操作了,元素属性现在也可以使用了。

注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm.$nextTick:

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

该钩子在服务器端渲染期间不被调用。

beforeUpdate

  • 类型:Function

  • 详细:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

  • 数据更新时调用,这里对需要更新 DOM 的数据进行更改。在进行删除事件侦听器之类的更改之前,此阶段适合任何逻辑。

updated

  • 类型:Function

  • 详细:

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

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

注意 updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick

updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the,代码只运行在
    // entire view has been re-rendered,整个视图已被重新渲染
  })
}

该钩子在服务器端渲染期间不被调用。

  • 组件DOM更新,组件更新完毕, DOM 更新之后立即调用此生命周期钩子

beforeDestroy

  • 类型:Function

  • 详细: 实例销毁之前调用。在这一步,实例仍然完全可用。 该钩子在服务器端渲染期间不被调用。

  • 解除绑定,销毁组件和监视器前执行,实例和所有函数仍然完好无损并在此处工作。在这个阶段你可以执行资源管理、删除变量和清理组件。

destroyed

  • 类型:Function

  • 详细: 实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 该钩子在服务器端渲染期间不被调用。

  • 销毁完成后执行

beforeUpdate

  • 类型:Function

  • 详细: 当数据发生改变时,还未重新渲染之前执行。

update

  • 类型:Function

  • 详细: 当数据发生改变时,重新渲染之后执行。

测试程序

html部分:

<div id="app">
	{{a}}
</div>

css部分:

var app=new Vue({
    el:'#app',
    data () {
    return {
      todos: [],
      allCounts: 0,
      filter: 'all',
      id: 0,
      states: ['all', 'active', 'completed']
    }
  },
  beforeCreate () {
    console.log('===========' + 'beforeCreated' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  },
  created () {
    console.log('===========' + 'created' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  },
  beforeMount () {
    console.log('===========' + 'beforeMount' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  },
  mounted () {
    console.log('===========' + 'mounted' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  },
  beforeUpdate () {
    console.log('===========' + 'beforeUpdate' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  },
  updated () {
    console.log('===========' + 'updated' + '=========')
    console.log(this.$el)
    console.log(this.$data)
    console.log(this.filter)
  }
 })

控制台显示如下(但是在挂载过程中有一个错误没有解决):

生命周期图例

从下图中,理解各个生命钩子在生命期中的位置