Vue 中 provide 和 reject 的使用详解和源码解析
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 的使用详解和源码解析相关推荐
- vue build text html,Vue中v-text / v-HTML使用实例代码详解_放手_前端开发者
废话少说,代码如下所述: /p> 显示123 /p> 补充:vuejs {{}},v-text 和 v-html的区别 {{message}} let app = new Vue({ el ...
- 并发编程五:java并发线程池底层原理详解和源码分析
文章目录 java并发线程池底层原理详解和源码分析 线程和线程池性能对比 Executors创建的三种线程池分析 自定义线程池分析 线程池源码分析 继承关系 ThreadPoolExecutor源码分 ...
- Vue 中 Dep 和 Observer 的用法详解
Vue 中响应式系统利用了订阅发布模式来实现基本的逻辑.本文将介绍其中的两个重要角色,他们就是Dep和Observer.其中Observer 是观察者和 Dep是订阅收集和发布者.另外watcher是 ...
- vue中监听属性watch使用详解
深度监听: (1)vue中的watch默认不监测对象内部值的改变(一层). (2)配置deep:true可以监测对象内部值改变(多层). 备注: (1)vue自身可以监测对象内部值的改变,但vue提供 ...
- Vue中ESlint配置文件eslintrc.js文件详解
最近在跟着视频敲项目时,代码提示出现很多奇奇怪怪的错误提示,百度了一下是eslintrc.js文件没有配置相关命令,ESlint的语法检测真的令人抓狂,现在总结一下这些命令的解释,方便以后查阅. 默认 ...
- VUE中$refs和$el的使用详解
ref: 给元素或者子组件注册引用信息 ref有三种用法: 1.ref加在普通元素上,获取用this.$ref.xxx可以获取到dom元素. <div ref="system" ...
- vue中的slot(插槽)详解
最近忙着写一些组件,关于插槽这一块自己还是用着 slot 和 slot-scope,然后看了一下文档的更新,于是又重新把"插槽"学习了一篇,下面一段是文档中的说明: 在 2.6.0 ...
- Android SharedPreferences 详解 源码解析
1.实现类 SharedPreferences 只是一个接口,其实现类是SharedPreferencesImpl. 工作流程分析: 创建sp 的时候,会去查看是否有bak文件,如果有的话,把bak文 ...
- beaninfo详解源码解析 java_Java后端精选技术:源码解析Spring Cloud Zuul
Zuul 架构图 在zuul中, 整个请求的过程是这样的,首先将请求给zuulservlet处理,zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext: ...
- beaninfo详解源码解析 java_【Spring源码分析】Bean加载流程概览
代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...
最新文章
- 变速更顺滑_1.6TGDI直喷发动机+7速湿式双离合自动变速箱,表现会如何?
- iOS开发-编译出错 duplicate symbols for architecture x86_64
- 推荐一个博客,或许给技术流的自己一些启示
- 正则表达式替换排除特定情况
- 64位c语言调用32位glibc,glibc fclose源代码阅读及伪造_IO_FILE利用fclose实现任意地址执行...
- mysql新建用户只能查看试图_Sql Server:创建用户并指定该用户只能看指定的视图,除此之外的都不让查看。...
- SPA(单页面应用)和MPA(多页面应用)
- bash配置文件的修改
- 讯飞输入法更新10.0版本 上线全新A.I.语音输入引擎
- Quartus II 12.1安装及破解
- 学生信息管理系统结构图
- 解决python中文乱码问题
- 程序员用实力把公司干倒闭了
- U盘可见空间只有200M的解决方法
- 基于JAVA宠物喂养资讯分享平台的设计与实现计算机毕业设计源码+系统+lw文档+部署
- 2021年全球化妆品阴离子表面活性剂行业调研及趋势分析报告
- 呆呆和你谈谈入职CVTE一个月的感受
- excel填充遇到的坑
- MySQL | 全内容
- 家乡的互联网---山西阳高