Vue——initInjections【九】

简介: Vue——initInjections【九】

前言

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

内容

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

initInjections

initInjections的方法位于scr/core/instance/inject.ts中;

export function initInjections(vm: Component) {
  // 解析inject,返回解析后的对象
  const result = resolveInject(vm.$options.inject, vm)
  if (result) {
    // 这里是为了告诉defineReactive不需要转为为响应式数据
    // 这里也正好印证了官方文档中provide 和 inject 绑定并不是可响应的。这是刻意为之的
    toggleObserving(false)
    Object.keys(result).forEach(key => {
      /* istanbul ignore else */
      if (__DEV__) {
        defineReactive(vm, key, result[key], () => {
          warn(
            `Avoid mutating an injected value directly since the changes will be ` +
              `overwritten whenever the provided component re-renders. ` +
              `injection being mutated: "${key}"`,
            vm
          )
        })
      } else {
        defineReactive(vm, key, result[key])
      }
    })
    toggleObserving(true)
  }
}
export function resolveInject(
  inject: any,
  vm: Component
): Record<string, any> | undefined | null {
  if (inject) {
    // inject is :any because flow is not smart enough to figure out cached
    // inject 是 any类型 因为flow不够智能无法计算缓存
    // 创建一个空对象用来存放结果
    const result = Object.create(null)
    // 获取key名
    // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys
    // 如果支持symbol和Reflect就使用 Reflect.ownKeys来获取所有key,否则使用Object.keys
    const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject)
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i]
      // #6574 in case the inject object is observed...
      // 如果是observed就跳过继续
      if (key === '__ob__') continue
      const provideKey = inject[key].from
      if (provideKey in vm._provided) {
        // 向父级_provided属性遍历查找属性值
        // 因为父级组件使用provide选项注入数据时会将注入的数据存入自身实例的_provided属性上
        result[key] = vm._provided[provideKey]
      } else if ('default' in inject[key]) {
        // 当前的数据key存在默认值即default属性
        // 需要对非原始值使用一个工厂方法可结合官方文档demo查看
        const provideDefault = inject[key].default
        result[key] = isFunction(provideDefault)
          ? provideDefault.call(vm)
          : provideDefault
      } else if (__DEV__) {
        warn(`Injection "${key as string}" not found`, vm)
      }
    }
    return result
  }
}

学无止境,谦卑而行.

目录
相关文章
|
5天前
|
JavaScript
vue组件中的插槽
本文介绍了Vue中组件的插槽使用,包括单个插槽和多个具名插槽的定义及在父组件中的使用方法,展示了如何通过插槽将父组件的内容插入到子组件的指定位置。
|
4天前
|
JavaScript
vue消息订阅与发布
vue消息订阅与发布
|
4天前
|
JavaScript 前端开发 IDE
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
|
4天前
|
JavaScript 前端开发 API
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
|
3天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
12 4
|
3天前
|
JavaScript
vue尚品汇商城项目-day07【51.路由懒加载】
vue尚品汇商城项目-day07【51.路由懒加载】
13 4
|
4天前
|
JavaScript 前端开发
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
|
3天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
9 2
|
4天前
|
JavaScript 前端开发 API
Vue学习笔记7:使用v-for指令渲染列表
Vue学习笔记7:使用v-for指令渲染列表
|
4天前
|
JavaScript
vue 函数化组件
vue 函数化组件
下一篇
无影云桌面