Vue源码学习之initInjections和initProvide

在进行源码阅读之前先让我们了解一个概念:provide/inject,这个是Vue在2.2.0版本新增的一个属性,按照Vue官网的说法,它的作用是:

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

简而言之就是由祖先组件提供了一个provide,provide里的属性可供所有的后代组件通过inject注入并调用,官网实例如下:

// 父级组件提供 'foo'
var Provider = {provide: {foo: 'bar'},// ...
}// 子组件注入 'foo'
var Child = {inject: ['foo'],created () {console.log(this.foo) // => "bar"}// ...
}
initInjections

该方法在初始化data/props之前被调用,主要作用是初始化vue实例的inject,让我们一行一行地看代码吧!

const result = resolveInject(vm.$options.inject, vm)

首先就是一个对inject进行处理的方法resolveInejct,让我们看下这个方法的实现。

const result = Object.create(null)
// 对Symbol进行不同的处理
const keys = hasSymbol ? Reflect.ownKeys(inject).filter(key => {/* istanbul ignore next */return Object.getOwnPropertyDescriptor(inject, key).enumerable
}) : Object.keys(inject)

先建立一个存放结果的空对象,由于provide支持Symbols作为key,所以要对symbol和普通的对象进行不同的处理。

for (let i = 0; i < keys.length; i++) {const key = keys[i]const provideKey = inject[key].fromlet source = vmwhile (source) {// 验证父组件链逐层向上查找provide,直到找到为止if (source._provided && hasOwn(source._provided, provideKey)) {result[key] = source._provided[provideKey]break}source = source.$parent}if (!source) {if ('default' in inject[key]) {const provideDefault = inject[key].defaultresult[key] = typeof provideDefault === 'function'? provideDefault.call(vm): provideDefault} else if (process.env.NODE_ENV !== 'production') {warn(`Injection "${key}" not found`, vm)}}
}
return result

这段代码主要就是对inject属性中的各个key进行遍历,然后沿着父组件链一直向上查找provide中和inject对应的属性,直到查找到根组件或者找到为止,然后返回结果。

让我们接着回到initInjections方法:

if (result) {toggleObserving(false)Object.keys(result).forEach(key => {/* istanbul ignore else */if (process.env.NODE_ENV !== 'production') {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)}

可以看到从provide中找到了inject的值之后,接下来就是对result的一些处理,比如在非生产环境会将result里的值定义成相应式的。

initProvide
function initProvide (vm: Component) {const provide = vm.$options.provideif (provide) {vm._provided = typeof provide === 'function'? provide.call(vm): provide}
}

initProvide基本没有什么内容,就是将$options里的provide赋值到当前实例上

Vue源码学习之initInjections和initProvide相关推荐

  1. vue源码学习--vue源码学习入门

    本文为开始学习vue源码的思路整理.在拿到vue项目源码的之后看到那些项目中的文件夹,会很困惑,不知道每个文件夹内的世界,怎么变换,怎样的魔力,最后产生了vue框架.学习源码也无从学起.我解决了这些困 ...

  2. Vue源码学习之Computed与Watcher原理

    前言  computed与watch是我们在vue中常用的操作,computed是一个惰性求值观察者,具有缓存性,只有当依赖发生变化,第一次访问computed属性,才会计算新的值.而watch则是当 ...

  3. Vue源码学习 - 组件化(三) 合并配置

    Vue源码学习 - 组件化(三) 合并配置 合并配置 外部调用场景 组件场景 总结 学习内容和文章内容来自 黄轶老师 黄轶老师的慕课网视频教程地址:<Vue.js2.0 源码揭秘>. 黄轶 ...

  4. VUE源码学习第一篇--前言

    一.目的 前端技术的发展,现在以vue,react,angular为代表的MVVM模式以成为主流,这三个框架大有三分天下之势.react和angular有facebook与谷歌背书,而vue是以一己之 ...

  5. Vue源码学习 - 组件化一 createComponent

    Vue源码学习 - 组件化一 createComponent 组件化 createComponent 构造子类构造函数 安装组件钩子函数 实例化 VNode 总结 学习内容和文章内容来自 黄轶老师 黄 ...

  6. Vue源码学习 - 准备工作

    Vue源码学习 - 准备工作 准备工作 认识Flow 为什么用 Flow Flow 的工作方式 类型推断 类型注释 数组 类和对象 null Flow 在 Vue.js 源码中的应用 flow实践 总 ...

  7. Vue源码学习: 关于对Array的数据侦听

    摘要 我们都知道Vue的响应式是通过Object.defineProperty来进行数据劫持.但是那是针对Object类型可以实现, 如果是数组呢? 通过set/get方式是不行的. 但是Vue作者使 ...

  8. 「Vue源码学习」常见的 Vue 源码面试题,看完可以说 “精通Vue” 了吗?

    Vue源码面试题 一.行时(Runtime)+ 编译器(Compiler) vs. 只包含运行时(Runtime-only) webpack Rollup Browserify 二.Vue 的初始化过 ...

  9. vue实例没有挂载到html上,vue 源码学习 - 实例挂载

    前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...

最新文章

  1. ubuntu下tesseract 4.0安装及参数使用
  2. 对 Linux 新手非常有用的 20 个命令
  3. 【STM32】 keil新建工程模板
  4. 用java程序for循环打印菱形_编写Java程序,应用for循环打印菱形、三角形
  5. 操作系统之进程管理:10、信号量机制(整形、记录型)
  6. mysql可扩展数据库_五大技巧提高MySQL可扩展性
  7. [转]将西部数据 My Passport Wireless 移动存储连接到任何支持的云存储上
  8. Bailian2856 计算邮资【入门】
  9. C#对文件的操作(创建、获取文件数量、删除)(读、写文件)
  10. 以前是传xml的吗_关于XML:新手入门.
  11. spring boot 设置时区
  12. 高校GIS房地产管理系统
  13. 数字后端设计流程小结
  14. 解决Jar包双击打不开!
  15. Counter对numpy数组进行统计
  16. 古诗文欣赏-春夜宴桃李园序
  17. 华为机试:计算最大乘积
  18. java过剩_中国的程序员数量是否已经饱和或者过剩?
  19. 项目上传至Gitte
  20. 网络通信误码率测试软件,DMR终端直通模式误码率测试软件的设计与实现

热门文章

  1. 几个小型数据库的比较
  2. 运放构成的简单占空比可调脉冲电路
  3. IDEA申请学生免费账号登陆失败
  4. ARP原理概述——基于WinPcap发送ARP请求数据包获取远程MAC地址
  5. 防火门-13869833139-杜子
  6. Win7注册表禁用USB接口、Win7组策略禁用USB端口
  7. Altium Designer输出生产文件Gerber、IPC、NC Drill、坐标文件--AD
  8. 400交换机呼叫中心的知识
  9. mysql根据经纬度查询距离在1000米范围内的数据
  10. chown和chgrp