Vue初始化之initLifecycle

2022/11/13 Vue

上一篇文章,我们看了Vue初始化时候设置render函数的执行上下文_renderProxy,这一篇我们继续往下读_init的源码,然后进入了初始化生命周期

...
initLifecycle(vm) // 初始化生命周期相关字段
...

这一行就是来处理初始化生命周期的,我们进入到这个函数来看看:

export function initLifecycle(vm: Component) {
  // mergeOptions 后的 options 赋值给 options 变量
  const options = vm.$options

  // 定位第一个非抽象的父组件,指非 keep-alive 和 transition等组件
  let parent = options.parent
  if (parent && !options.abstract) {
    // 如果父实例 parent 是抽象组件
    // 就继续向上找父实例
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent
    }
    // 把 vm 实例放到非抽象父组件的 $children 里
    parent.$children.push(vm)
  }

  // 指定已创建的实例之父实例,在两者之间建立父子关系
  vm.$parent = parent
  // 当前组件树的根 Vue 实例,没有父组件就是自己
  vm.$root = parent ? parent.$root : vm

  // 存放子组件
  vm.$children = []
  // 存放子组件或者本身的 refs
  vm.$refs = {}

  // 初始化 provide
  vm._provided = parent ? parent._provided : Object.create(null)
  // 初始化实例的 watcher 实例对象
  vm._watcher = null
  // 设置 keep-alive 中该实例的状态
  vm._inactive = null
  // 设置 keep-alive 中该实例的状态
  vm._directInactive = false
  // 实例是否完成挂载 - mounted
  vm._isMounted = false
  // 实例是否已经被销毁 - destroyed
  vm._isDestroyed = false
  // 当前实例是否正在被销毁,还没有销毁完成 - beforeDestory 到 destroyed 之间
  vm._isBeingDestroyed = false
}

这个函数比较简单,就是在给当前实例初始化一些生命周期相关的属性

...
// mergeOptions 后的 options 赋值给 options 变量
const options = vm.$options
...

拿到当前实例的 options,这个 options 是前面合并之后的options。

...
// 定位第一个非抽象的父组件,指非 keep-alive 和 transition等组件
let parent = options.parent
if (parent && !options.abstract) {
  // 如果父实例 parent 是抽象组件
  // 就继续向上找父实例
  while (parent.$options.abstract && parent.$parent) {
    parent = parent.$parent
  }
  // 把 vm 实例放到非抽象父组件的 $children 里
  parent.$children.push(vm)
}
...

这里是在找当前实例的父组件,主要是为了把像keep-alive,transition等这些抽象组件给去除,找到第一个非抽象组件的父组件。如果有父组件,把当前实例放在父组件的$Children里。

...
// 指定实例的父实例,建立父子关系
vm.$parent = parent
// 当前组件树的根 Vue 实例,没有父组件就是自己
vm.$root = parent ? parent.$root : vm

// 存放子组件
vm.$children = []
// 存放子组件或者本身的 refs
vm.$refs = {}
...

这里是在处理当前组件的父组件,子组件,根实例,refs等。

...
// 初始化 provide
vm._provided = parent ? parent._provided : Object.create(null)
// 初始化实例的 watcher 实例对象
vm._watcher = null
// 设置 keep-alive 中该实例的状态
vm._inactive = null
// 设置 keep-alive 中该实例的状态
vm._directInactive = false
// 实例是否完成挂载 - mounted
vm._isMounted = false
// 实例是否已经被销毁 - destroyed
vm._isDestroyed = false
// 当前实例是否正在被销毁,还没有销毁完成 - beforeDestory 到 destroyed 之间
vm._isBeingDestroyed = false
...

这上面的代码,是在处理实例的一些属性和状态,比如provide属性,watcher实例等,还有组件在keep-alive中的状态,最后就是生命周期的状态,是否挂载,是否被销毁,是否正在销毁等。

initLifecycle函数逻辑非常简单,就是给实例初始化了一些属性,包括以$开头的供用户使用的外部属性,也包括以_开头的供内部使用的内部属性。