Vue 提供了provide 和reject 属性为高阶组件提供了便利的数据传递。

一:使用详解

provide:Object | () => Object
inject:Array<string> | { [key: string]: string | Symbol | Object }

完整的用法

// 父级组件提供 'foo'
var Provider = {data () {return  {x: 'test'}}// 可以直接使用对象,对象包含需要提供的key:“value”provide: {foo: 'bar'},// 可是设置provide 为一个函数,函数返回一个provide属性,this指向vue实例,所以可以调用组件data里的值得provide () {return {a: this.x}},// ...
}// 子组件注入 'foo'
var Child = {// inject可以是一个数组,数组里包含需要注入的key的字面量inject: ['foo'],// inject 可以是一个对象inject: {foo: 'foo'},// inject 可以设置默认值,所以可以inject的指可以在provide里不存在inject: {foo: {default: 'default value'}},// default 值也可是一个有返回值的函数inject: {foo: {default: () => {return [1,2,3]}}},// 完整的带默认值的写法, a 是provide中提供的key的字面量inject: {foo: {from: 'a',default: 'default value'}},created () {console.log(this.foo) // => "bar"}// ...
}

二:源码解读

// 初始化组件的时候,初始话provide属性的方法
function initProvide (vm) {var provide = vm.$options.provide;if (provide) {vm._provided = typeof provide === 'function' // 判断如果传入的方法是provide是函数,执行函数获取到返回的对象,否则直接返回? provide.call(vm): provide;}}
// vue中处理inject  属性function initInjections (vm) {var result = resolveInject(vm.$options.inject, vm); // 见下一个函数if (result) {toggleObserving(false); // 关闭响应式数据定义开关,保证在调用 defineReactive$$1 的时候不对数据进行响应式绑定Object.keys(result).forEach(function (key) {/* istanbul ignore else */{defineReactive$$1(vm, key, result[key], function () { // 这里是保证inject属性不能设置成响应式的,否则会发出警告warn("Avoid mutating an injected value directly since the changes will be " +"overwritten whenever the provided component re-renders. " +"injection being mutated: \"" + key + "\"",vm);});}});toggleObserving(true);// 打开响应开关}}function resolveInject (inject, vm) {if (inject) {// inject is :any because flow is not smart enough to figure out cachedvar result = Object.create(null);var keys = hasSymbol? Reflect.ownKeys(inject): Object.keys(inject);for (var i = 0; i < keys.length; i++) {var key = keys[i];// #6574 in case the inject object is observed...if (key === '__ob__') { continue }var provideKey = inject[key].from;var source = vm;// 循环向上寻找父节点,直到找到包含有inject key的provide对象while (source) {if (source._provided && hasOwn(source._provided, provideKey)) {result[key] = source._provided[provideKey];break}source = source.$parent;}if (!source) { // 如果发现父或者父的父没有inject里的key,if ('default' in inject[key]) { // 就去找设置的default的值var provideDefault = inject[key].default;result[key] = typeof provideDefault === 'function'? provideDefault.call(vm): provideDefault;} else {warn(("Injection \"" + key + "\" not found"), vm);}}}return result}}

可以发现,通过这种方式,我们又为组件提供了一种从父向子传递数据的一种方式,而且不一定是父子,爷孙组件也可以传递。但是官方不建议我们在业务组件中这么使用,因为如果通过这样的方式会使组件之间的耦合度变得很高,尤其是当用户滥用跨多级组件进行传值,代码的稳定性和可维护性将大大降低。

Vue 中 provide 和 reject 的使用详解和源码解析相关推荐

  1. vue build text html,Vue中v-text / v-HTML使用实例代码详解_放手_前端开发者

    废话少说,代码如下所述: /p> 显示123 /p> 补充:vuejs {{}},v-text 和 v-html的区别 {{message}} let app = new Vue({ el ...

  2. 并发编程五:java并发线程池底层原理详解和源码分析

    文章目录 java并发线程池底层原理详解和源码分析 线程和线程池性能对比 Executors创建的三种线程池分析 自定义线程池分析 线程池源码分析 继承关系 ThreadPoolExecutor源码分 ...

  3. Vue 中 Dep 和 Observer 的用法详解

    Vue 中响应式系统利用了订阅发布模式来实现基本的逻辑.本文将介绍其中的两个重要角色,他们就是Dep和Observer.其中Observer 是观察者和 Dep是订阅收集和发布者.另外watcher是 ...

  4. vue中监听属性watch使用详解

    深度监听: (1)vue中的watch默认不监测对象内部值的改变(一层). (2)配置deep:true可以监测对象内部值改变(多层). 备注: (1)vue自身可以监测对象内部值的改变,但vue提供 ...

  5. Vue中ESlint配置文件eslintrc.js文件详解

    最近在跟着视频敲项目时,代码提示出现很多奇奇怪怪的错误提示,百度了一下是eslintrc.js文件没有配置相关命令,ESlint的语法检测真的令人抓狂,现在总结一下这些命令的解释,方便以后查阅. 默认 ...

  6. VUE中$refs和$el的使用详解

    ref: 给元素或者子组件注册引用信息 ref有三种用法: 1.ref加在普通元素上,获取用this.$ref.xxx可以获取到dom元素. <div ref="system" ...

  7. vue中的slot(插槽)详解

    最近忙着写一些组件,关于插槽这一块自己还是用着 slot 和 slot-scope,然后看了一下文档的更新,于是又重新把"插槽"学习了一篇,下面一段是文档中的说明: 在 2.6.0 ...

  8. Android SharedPreferences 详解 源码解析

    1.实现类 SharedPreferences 只是一个接口,其实现类是SharedPreferencesImpl. 工作流程分析: 创建sp 的时候,会去查看是否有bak文件,如果有的话,把bak文 ...

  9. beaninfo详解源码解析 java_Java后端精选技术:源码解析Spring Cloud Zuul

    Zuul 架构图 在zuul中, 整个请求的过程是这样的,首先将请求给zuulservlet处理,zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext: ...

  10. beaninfo详解源码解析 java_【Spring源码分析】Bean加载流程概览

    代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...

最新文章

  1. 变速更顺滑_1.6TGDI直喷发动机+7速湿式双离合自动变速箱,表现会如何?
  2. iOS开发-编译出错 duplicate symbols for architecture x86_64
  3. 推荐一个博客,或许给技术流的自己一些启示
  4. 正则表达式替换排除特定情况
  5. 64位c语言调用32位glibc,glibc fclose源代码阅读及伪造_IO_FILE利用fclose实现任意地址执行...
  6. mysql新建用户只能查看试图_Sql Server:创建用户并指定该用户只能看指定的视图,除此之外的都不让查看。...
  7. SPA(单页面应用)和MPA(多页面应用)
  8. bash配置文件的修改
  9. 讯飞输入法更新10.0版本 上线全新A.I.语音输入引擎
  10. Quartus II 12.1安装及破解
  11. 学生信息管理系统结构图
  12. 解决python中文乱码问题
  13. 程序员用实力把公司干倒闭了
  14. U盘可见空间只有200M的解决方法
  15. 基于JAVA宠物喂养资讯分享平台的设计与实现计算机毕业设计源码+系统+lw文档+部署
  16. 2021年全球化妆品阴离子表面活性剂行业调研及趋势分析报告
  17. 呆呆和你谈谈入职CVTE一个月的感受
  18. excel填充遇到的坑
  19. MySQL | 全内容
  20. 家乡的互联网---山西阳高

热门文章

  1. 分布式系统可观测性之应用业务指标监控
  2. 编译MTK系统源码时checking Env失败的解决方法
  3. 透明网桥的自学习算法
  4. 信息系统项目管理基础
  5. 17分钟过桥,过桥最短时间问题
  6. 高数篇:05柯西定理和泰勒公式
  7. Excel使用技巧随笔
  8. 华三路由交换配置命令_华为-华三交换机路由器命令大全
  9. 古风排版 python
  10. 【fgm.cc练习4-1】setTimeout应用:重点不是setTimeout,而是各种布局令我头大