返回

从源码上来看,Vue对象的每个生命周期钩子前都干了什么?

前端

Vue 生命周期钩子执行顺序

Vue 对象的生命周期钩子按照如下顺序执行:

  • beforeCreate: 在实例创建之前调用。此时,实例尚未初始化,因此无法访问数据或方法。
  • created: 在实例创建之后立即调用。此时,实例已经初始化,但还未挂载到 DOM。
  • beforeMount: 在实例挂载到 DOM 之前调用。此时,实例已经可以访问 DOM 元素,但还未对它们进行任何操作。
  • mounted: 在实例挂载到 DOM 之后立即调用。此时,实例已经可以对 DOM 元素进行操作了。
  • beforeUpdate: 在实例更新之前调用。此时,实例的数据已经更新,但还未更新 DOM。
  • updated: 在实例更新之后立即调用。此时,实例已经更新了 DOM。
  • beforeDestroy: 在实例销毁之前调用。此时,实例的数据和方法仍然可用,但它们即将被销毁。
  • destroyed: 在实例销毁之后立即调用。此时,实例的所有数据和方法都已销毁。

源码分析

让我们通过源码来具体分析每个生命周期钩子在执行前的操作。

  • beforeCreate:
beforeCreate () {
  // ...

  // 初始化 props
  this._props = observeProps(this, this.$options.propsData || {})
  // 初始化 methods
  this._methods = this.$options.methods
  // 初始化 computed
  this._computed = this.$options.computed
  // 初始化 watch
  this._watcher = this._initWatch(this._watchers || {})
  // ...
}

beforeCreate 钩子中,Vue 实例对象会初始化 props、methods、computed 和 watch 等属性,以便在后续生命周期中使用。

  • created:
created () {
  // ...

  // 初始化生命周期
  this._isMounted = false
  this._isDestroyed = false
  this._vnode = null
  this._staticTrees = null
  // ...
}

created 钩子中,Vue 实例对象会初始化一些生命周期相关的属性,如 _isMounted_isDestroyed_vnode_staticTrees 等。

  • beforeMount:
beforeMount () {
  // ...

  // 创建 vnode
  this._vnode = createElement(this.$options._renderProxy, this._parentVnode)
  // 创建静态树
  this._staticTrees = this.$options.staticRenderFns.map(function (fn) {
    return createElement(fn, this._parentVnode)
  })
  // ...
}

beforeMount 钩子中,Vue 实例对象会创建 vnode 和静态树,以便在后续的 mounted 钩子中挂载到 DOM。

  • mounted:
mounted () {
  // ...

  // 挂载 vnode
  this._update(this._vnode, this._parentVnode)
  // 调用 mounted 钩子
  this.$nextTick(() => {
    this._mounted = true
    this._watcher = this._initWatch(this._watchers || {})
    callHook(this, 'mounted')
  })
  // ...
}

mounted 钩子中,Vue 实例对象会将 vnode 挂载到 DOM,并调用 mounted 钩子函数。

  • beforeUpdate:
beforeUpdate () {
  // ...

  // 更新组件状态
  this._preState = this._state
  this._preProps = this._props
  this._vnode = this._vnode.clone()
  // ...
}

beforeUpdate 钩子中,Vue 实例对象会更新组件的状态,包括 _state_props_vnode 等属性。

  • updated:
updated () {
  // ...

  // 调用 updated 钩子
  callHook(this, 'updated')
  // ...
}

updated 钩子中,Vue 实例对象会调用 updated 钩子函数。

  • beforeDestroy:
beforeDestroy () {
  // ...

  // 销毁组件状态
  this._isBeingDestroyed = true
  // ...
}

beforeDestroy 钩子中,Vue 实例对象会销毁组件的状态,包括 _isBeingDestroyed 等属性。

  • destroyed:
destroyed () {
  // ...

  // 调用 destroyed 钩子
  callHook(this, 'destroyed')
  // ...
}

destroyed 钩子中,Vue 实例对象会调用 destroyed 钩子函数。

总结

通过对 Vue 源码的分析,我们了解了 Vue 对象的每个生命周期钩子在执行前的具体操作。这些操作为 Vue 实例对象提供了初始化、挂载、更新和销毁等功能,确保了 Vue 实例对象能够正常运行。