Vue源码分析之初始化生命周期

·  阅读 66

这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

前言

在前边看new Vue实例的过程中已经了解到在创建Vue实例以后首先就进入初始化阶段。在这个阶段会调用_init方法,里边有几个初始化函数。

_init方法是定义在Vue原型上的,在src/core/instance/init.js

initLifecycle(vm)
initEvents(vm)
initRender(vm)

callHook(vm, 'beforeCreate')

initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props

callHook(vm, 'created')
复制代码

在看代码之前,先来看下Vue官方提供的生命周期图中关于初始化这块的流程图:

image.png

这个图完美的展现了_init方法中初始化参数与钩子函数执行的顺序:

  • 初始化生命周期与事件(initLifecyle + initEvents + initRender)

  • 执行beforeCreate钩子函数

  • 初始化injections与响应式(initInjections + initState + initProvide)

  • 执行created钩子函数

接下来就来具体看下这几个初始化函数的具体实现,由于内容过多,这篇文先只看是如何初始化生命周期。先来看下initLifecycle方法:

initLifecycle

initLifecycle定义在src/core/instance/lifecycle.js中。

export function initLifecycle (vm: Component) {
  const options = vm.$options

  // locate first non-abstract parent
  let parent = options.parent
  if (parent && !options.abstract) {
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent
    }
    parent.$children.push(vm)
  }

  vm.$parent = parent
  vm.$root = parent ? parent.$root : vm

  vm.$children = []
  vm.$refs = {}

  vm._watcher = null    //渲染Watcher
  vm._inactive = null   //缓存组件相关,标志是否被激活
  vm._directInactive = false
  vm._isMounted = false   
  vm._isDestroyed = false
  vm._isBeingDestroyed = false  //标志是否正在被销毁,介于生命周期beforeDestroy与destroyed之间
}
复制代码

代码很简单,主要分为两部分:

  • 初始化当前vm实例的祖先关系以及refs属性

  • 初始化生命周期钩子相关的变量

值的关注的是在建立组件的父子关系时,会先判断当前vm的abstract是否为true。如果当前vm实例abstract属性为false,则还要while循环去判断父组件的abstract属性,如果为true则会一直向上找,直到找到abstract为false的父组件为止。

如果组件设置了abstract为true,即代表它是一个抽象组件,如keep-alive,transition等,则直接跳过,不关联父子关系。这就是为什么官方说keep-alive抽象组件是不会出现在组件的父组件链中。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改