前言:

之前在 Vue 中进行组件通信一般都会使用 props,开始使用 provide/inject 是非常偶然的一次尝试。
当时在开发中需要实现祖孙组件,甚至祖祖祖祖孙组件之间的通信,在这种多层级场景下,props 就显得太过累赘了,由于是进行设计器(插件)开发,为了提高插件的可复用性,减少不必要的包依赖,倾向于在不引入 Vuex 的情况下解决这个问题,那么就应该看看 vue 本身,是否具有这种能力,就在这个时候,我发现了 provide/inject。

官方定义

我们先来看看 Vue 官方的定义是什么:

provide/inject 是 Vue 在 2.2.0 版本新增的 API,官网这段定义看起来好像有点难理解,通俗的讲,就是 provide 可以在祖先组件中指定我们想要提供给后代组件的数据或方法,而在任何后代组件中,我们都可以使用 inject 来接收 provide 提供的数据或方法。

举个

// 父级组件提供 'foo'
<template><div><div>{{foo}}</div><son></son></div>
</template><script>
import Son from "./Son";
export default {name: "parent",components: { Son },provide() {return {foo: this.foo};},data() {return {foo: "测试",};},mounted() {console.log(this.foo)},
};
</script>//子级组件,不接收
<template><grandSon></grandSon>
</template><script>
import grandSon from "./grandSon";
export default {name: "son",components: { grandSon },
};
</script>//孙级组件,接收foo
<template><div>{{foo}}</div>
</template><script>
export default {name: "grandSon",inject: ["foo"],mounted() {console.log(this.foo)},
};
</script>

在这里我们可以发现孙组件越过子组件接收了父组件注入的数据,我们可以理解为爷爷越过爸爸偷偷给孙子买了冰激凌,这是一组最简单的用法,当层级继续增加时,仍可通过这种方式由父组件直接跨域多个层级向后代组件注入数据。
有一点需要特别注意的是,实际上我们可以将当前组件inject获取的数据直接赋值给它本身的data或props,不过官网提示我们,这是在Vue2.2.1版本才实现的功能,在这之前,必须先进行props和data数据的初始化。

接下来 2 个例子只工作在 Vue 2.2.1 或更高版本。低于这个版本时,注入的值会在 propsdata 初始化之后得到。

响应更新

在尝试中我们发现,由于Vue的单向流关系,实际上如果在parent中改变了初始传入的foo的值以后,grandSon并不会得到改变后的值,也就是在这个时候,父孙组件的数据出现了不一致的情况,我们肯定是希望拿到的数据是一致的,怎么来解决这个问题呢,官网还有一句提示为我们提供了解释。

提示:provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。 也就是指,我们需要人为的将这组数据关系变成可响应的,哦,我们之前的foo是一个字符串,基本数据类型是不具有响应特性的,那么,我们可能需要传递一个对象。

再举个

// 改造一下父级组件提供 'foo'
<template><div><div>{{foo}}</div><son></son></div>
</template><script>
import Son from "./Son";
export default {name: "parent",components: { Son },provide() {return {foo: this.foo};},data() {return {foo: {foo: "测试"},,};},mounted() {console.log(this.foo)},
};
</script>

在这个栗子中,改造了一下父组件提供的数据,测试发现,foo变成了一组可响应的数据。经过尝试我发现在这种情况下如果在孙组件改变inject中foo的值,也会响应的更新到父组件中,当然为了保护单向数据流机制,最佳实践还是不要在子组件里更改inject(虽然 sync 也破坏了单向数据流)。

默认值设置

在 2.5.0+ 的注入可以通过设置默认值使其变成可选项

<script>
export default {name: "grandSon",inject: {foo: {from: 'bar',default: () => [1, 2, 3]}},mounted() {console.log(this.foo)},
};
</script>:

在2.5.0 版本之后的版本中可以为inject提供默认值了,如果它需要从一个不同名字的 property 注入,则使用 from 来表示其源 property,与 prop 的默认值类似,需要对非原始值使用一个工厂方法。

呱唧呱唧,那基本用法我们就讲到这里了,归根结底,既然provide/inject 这么方便,为什么 Vue 官方还要推荐我们使用 Vuex进行数据管理呢?

明显的缺点

provide/inject 的缺点还是非常明显的:

  • 当多个后代组件同时依赖同一个父组件提供数据时,只要任一组件对数据进行了修改,所有依赖的组件都会受到影响,实际上是增加了耦合度。
  • 任意层级访问使数据追踪变的比较困难,你并不能准确的定位到是哪一个层级对数据进行了改变,当数据出现问题时,尤其是多人协作时,可能会大大增加问题定位的损耗。

值得肯定的优点

万事万物都有把双刃剑,有缺点自然也有优点,在进行组件库或高级插件开发时,provide/inject 仍然是一个不错的选择。

留坑待补(应当不会鸽)

  • 从Vue生命周期源码来看provide/inject的执行过程
  • 插件/组件库应用实例(同样的功能实现与Vuex进行对比)

最后

其实之前的笔记都是写给自己看的,这还是真正意义上的第一篇热乎乎的博客,emmm感觉还有些地方没有讲的很明白,也还留坑了一些内容后续会慢慢完善,输出真是不易的过程,不过会继续努力学习提高哒,有问题欢迎指出,会及时更正,奥里给!

最后的最后

给我们的小组卖个安利,组内都是可爱的程序媛小姐姐哦,欢迎热爱前端的小姐妹们加入我们,一起学习,共同进步【有意请留言或私信,社畜搬砖不及时,但看到会立刻回复】

export default用法vue_Vue组件通信—provide/inject相关推荐

  1. vue组件通信provide/inject

    组件通信 provide/inject 一对使用 父组件通过provide提供数据 子组件通过inject注入值 非响应式,可通过对象内属性的方式进行修改 解决深层次组件通信 举例: 在app组件下引 ...

  2. is属性用法 vue_vue组件讲解(is属性的用法)模板标签替换操作

    vue中is的属性引入是为了解决dom结构中对放入html的元素有限制的问题,譬如ul里面要接上li的标签,引入is的属性后,你完全可以写成这样 这样会保证dom结构在浏览器的正常渲染,尽量避免在不正 ...

  3. Vue3+Typescript学习笔记(十)组件通信--父子组件通信(props,$emit),非父子组件通信(provide和inject,mitt库)

    一.认识组件的嵌套 1. App单独开发 前面我们是将所有的逻辑放到一个App.vue中: 在之前的案例中,我们只是创建了一个组件App: 如果我们一个应用程序将所有的逻辑都放在一个组件中,那么这个组 ...

  4. Vue 组件化通信 provide inject ,dispatch ,boardcast

    入门 作为前端最容易上手的框架,Vue入门其实没啥说的,我放一段清单的代码,大家能看懂就说明能上手了 <template><div id="app">< ...

  5. Vue中的export和export default{}用法

    目录 一.export 的使用 二.export default 的使用 三.两者之间的区别 区别 1: 区别 2: 区别 3:  在JavaScript ES6中,export 与 export d ...

  6. vue组件通信的几种方法

    vue中我们最常使用的就是父子之间的通信还有全局数据管理vuex了,下面粗略说一下vue组件通信的几种方法 组件通信的几种方式 1.父子组件通信 2.兄弟组件通信 3.跨多层级组件通信 4.任意组件( ...

  7. react组件通信-逆战1913

    父组件向子组件通信 父组件: import React,{ Component } from "react"; import Childre from"./Childre ...

  8. vue跨组件之间传值Provide/Inject

    官网传送门:inject  Vue2.2.0+ # 背景   关于Vue组件的通讯方式相信大家能倒背如流 父子组件:通过prop,$emit,[$root,$parent,$children] 非父子 ...

  9. Vue组件通讯方式 provide/inject 介绍以及使用场景

    文章目录 vue的通讯方式 provide / inject的缺点 使用办法 代码案例展示一(provide字符串) 代码案例展示二(provide返回一个方法,并且方法返回字符串) vue的通讯方式 ...

最新文章

  1. cufflinks基于dataframe数据绘制股票数据:直方图、时序图
  2. python 从url中提取域名和path
  3. Lambda方法推导(method references)
  4. 初学Java Web——Servlet(一)
  5. os.system方法
  6. HTTP的同源策略与跨域资源共享(CORS)机制
  7. turtle库绘制圆_Python绘画:应用Turtle库绘制“抖音艺术字”
  8. SQLserver语句命令
  9. mysql 操作类 C .net_.NET MYSQL数据库操作基类( C#源码)
  10. mybatis insert 动态生成插入的列及插入的值
  11. 在 npm script 中使用环境变量
  12. NIPS论文遭受全面质疑:论证过程普遍不完整,又何谈对错?
  13. Word交叉引用连续引用多个参考文献
  14. 使用数位板遇到的常见问题及解决方法
  15. 野生的男人,家养的猪
  16. 短视频素材怎么找?怎么做短视频运营?
  17. 周末imac机重装win7,装得我抓狂
  18. Complex-Valued CNN and Its Application in Polarimetric SAR Image Classification
  19. python将图片批量保存至word文档中
  20. 一抹阳光,几缕思绪...

热门文章

  1. 判断小米华为等系统 MD
  2. 产品经理 - 学习书籍
  3. java 静态变量生命周期(类生命周期)
  4. 怎样提高团队管理能力5
  5. 【转】网络编程常见问题总结
  6. 【转】体验 Silverlight 5 3D开发之环境搭配篇
  7. c语言创建线程函数怎么使用方法,如何用C语言实现多线程
  8. java 字节取位_java位 、字节 、字符的梳理
  9. 饥荒机器人怎么用避雷针充电_新款iPhone充电线怎么这么好看~安卓也可以用!...
  10. linux 虚拟机新增磁盘,linux(虚拟机)下新增磁盘配置