vue生命周期beforeCreate()前做了什么

概念

当我们执行 new Vue()开始到被创建完成,vue需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

beforeCreate

问题:beforeCreate为vue初始化过程中第一个钩子函数,那么从new Vue()到beforeCreate过程它做了什么?

在这里插入图片描述

从图中我们可以到,这个过程中,进行了初始化事件、生命周期
我们从vue2源码上看看
1、vue-dev\src\core\instance\index.js

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

//初始化mixin
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

我们找到vue入口文件,可以发现vue函数中执行了_init(options)初始化方法,但是这个方法并没有在当前文件定义。函数的外面执行了initMixin(Vue),我们可以得出,这是一个初始化的mixin。

2.\vue-dev\src\core\instance\init.js

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // a flag to avoid this being observed
    vm._isVue = true
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    // expose real self
    vm._self = vm
    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')
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

我们可以看到,在执行beforeCreate之前,做了几件事:初始化生命周期initLifecycle,初始化事件initEvents,初始化RenderinitRender。
3.初始化生命周期initLifecycle
路径: \vue-dev\src\core\instance\lifecycle.js

export function initLifecycle (vm: Component) {
  // 获取new vue传入的参数对象
  const options = vm.$options

  // 定位vm选项第一个非抽象父级,没有的话为undefined
  let parent = options.parent
  //如果当前实例有父实例并且当前实例abstract为false
  if (parent && !options.abstract) {
    // 当父实例的parent是抽象组件,向上查找,直到找到最顶级不是抽象的父实例
    while (parent.$options.abstract && parent.$parent) {
      parent = parent.$parent
    }
    // parent第一个非抽象parent,添加vm实例为子元素
    parent.$children.push(vm)
  }
  //vue实例定义$parent、$root、$children、$refs属性及其他属性
  // 指定已创建的实例之父实例,在两者之间建立父子关系。子实例可以用  this.$parent 访问父实例,子实例被推入父实例的 $children 数组中
  vm.$parent = parent
  // 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己
  vm.$root = parent ? parent.$root : vm
  //  当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。
  vm.$children = []
  // 一个对象,持有已注册过 ref 的所有子组件
  vm.$refs = {}
  // 组件实例相应的 watcher 实例对象
  vm._watcher = null
  // 表示keep-alive中组件状态,如被激活,该值为false,反之为true
  vm._inactive = null
  // 也是表示keep-alive中组件状态的属性。
  vm._directInactive = false
  // 当前实例是否完成挂载(对应生命周期图示中的mounted)
  vm._isMounted = false
  // 当前实例是否已经被销毁(对应生命周期图示中的destroyed)
  vm._isDestroyed = false
  // 当前实例是否正在被销毁,还没有销毁完成(介于生命周期图示中deforeDestroy和destroyed之间)
  vm._isBeingDestroyed = false
}

我们可以看到,初始化生命周期函数中,vue判断当前组件是否存在父组件,如果存在,循环找到第一个非抽象父组件,并将vm push进去作为子元素。并且定义了$parent、$root、$children、$refs属性及其他属性。
注:
抽象组件:
在这里插入图片描述
就像官网说的一样,它在代码中存在,但是自身不会渲染一个 DOM 元素,也不会出现在父组件链中,不会体现在DOM树上。则非抽象组件正好相反。
定义的属性说明见代码块注释

4.初始化事件initEvents
路径:\vue-dev\src\core\instance\events.js

export function initEvents (vm: Component) {
	...
}
...省略
Vue.prototype.$once = function(){...}
Vue.prototype.$off= function(){...}
Vue.prototype.$emit = function(){...}
Vue.prototype.$on= function(){...}

我们可以看到,初始化事件其实是在Vue的原型上定义$once、$off、$emit、$on函数
5.初始化Render initRender
路径:\vue-dev\src\core\instance\render.js

export function initRender (vm: Component) {
...省略
  vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
  // normalization is always applied for the public version, used in
  // user-written render functions.
  vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
...省略
}

我们可以看到,初始化Render其实是封装createElement函数,让我们调用更简单。

所以,在调用beforeCreate()函数前,vue主要做了vm实例一些属性的定义和createElement()方法的封装。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值