Vue——initProvide【十一】

前言

前面我们简单的了解了 vue 初始化时的一些大概的流程,这里我们详细的了解下具体的内容;

内容

这一块主要围绕init.ts中的initProvide进行剖析,初始化生命周期之后紧接着。

initProvide

export function initProvide(vm: Component) {
  const provideOption = vm.$options.provide
  if (provideOption) {
    // 获取provided的对象
    const provided = isFunction(provideOption)
      ? provideOption.call(vm)
      : provideOption

    // 如过不是object对象且为null直接返回
    if (!isObject(provided)) {
      return
    }
    // 解析provide
    const source = resolveProvided(vm)
    // IE9 doesn't support Object.getOwnPropertyDescriptors so we have to
    // iterate the keys ourselves.

    const keys = hasSymbol ? Reflect.ownKeys(provided) : Object.keys(provided)
    // IE9不支持Object.getOwnPropertyDescriptors所以这里必须自己去迭代keys
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i]
      Object.defineProperty(
        source,
        key,
        Object.getOwnPropertyDescriptor(provided, key)! // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
      )
    }
  }
}

resolveProvided

resolveProvided位于src/v3/apilnject.ts

export function resolveProvided(vm: Component): Record<string, any> {
  // by default an instance inherits its parent's provides object
  // but when it needs to provide values of its own, it creates its
  // own provides object using parent provides object as prototype.
  // this way in `inject` we can simply look up injections from direct
  // parent and let the prototype chain do the work.
  // 默认情况下,实例继承其父级的provides对象,
  // 但当它需要提供自己的值时,
  // 它会使用父级provides对象作为原型创建自己的provide对象。
  // 通过这种方式,在“inject”中,我们可以简单地从直接父级查找注入,并让原型链来完成工作。
  const existing = vm._provided
  const parentProvides = vm.$parent && vm.$parent._provided
  // 如果父级上的_provided和实例上的_provided一致,就将父级上的parentProvides赋给实例上的_provided
  // 否则直接返回实例上的属性
  if (parentProvides === existing) {
    return (vm._provided = Object.create(parentProvides))
  } else {
    return existing
  }
}
posted @ 2023-03-28 19:38  。思索  阅读(28)  评论(0编辑  收藏  举报