组件通信——provide 和 inject 实现爷孙组件通信

简介: 组件通信——provide 和 inject 实现爷孙组件通信

provide 和 inject 实现爷孙组件通信
介绍
provide 和 inject 是 Vue.js 提供的一种在组件之间共享数据的机制,它允许在组件树中的任何地方注入依赖项。这对于跨越多个层级的组件间通信特别有用,因此无需手动将 prop 数据逐层传递下去。

provide:

在一个组件中使用 provide 方法来定义要提供的数据或方法。

provide 方法返回一个对象,该对象包含了要提供的数据或方法。

inject:

在另一个组件中使用 inject 方法来注入这些数据或方法。

inject 方法接收一个数组或对象,指明要注入的数据或方法名称。

实现原理
provide 方法

当你在组件中定义 provide 方法时,Vue.js 会执行以下步骤:

创建 provide 对象:
provide() {
return {
sharedData: 'Hello from App component!',
updateData: this.updateData
};
}
1
2
3
4
5
6
附加到组件实例:Vue.js 会在组件实例上附加一个 _provided 属性,存储 provide 方法返回的对象。
inject 方法

当你在组件中定义 inject 方法时,Vue.js 会执行以下步骤:

查找 provide 对象:Vue.js 会从当前组件及其祖先组件中查找 _provided 属性。
如果找到,则将相应的数据或方法注入到当前组件中。

注入到组件实例:注入的数据或方法会作为属性添加到当前组件实例上,可以通过 this 访问。

优点
简化多层级组件通信:不需要逐层传递 props,可以方便地在组件树中的任意位置提供和注入数据。

灵活性高:可以动态地提供和注入数据或方法,适用于多种场景。

减少代码冗余:减少了逐层传递 props 的代码量,提高了代码的可读性和可维护性。

缺点
调试困难:由于数据传递路径不明确,调试时可能比较困难,尤其是在大型项目中。

组件关系模糊:组件之间的依赖关系变得不清晰,可能导致代码难以理解和维护。

性能开销:大量使用 provide 和 inject 可能导致额外的性能开销,特别是在复杂的应用中。

滥用问题:如果过度使用 provide 和 inject,可能会导致组件之间的耦合度过高,降低代码的可维护性。

vue2.x 使用
grandpa.vue 组件(爷)

使用 provide 方法提供了 message, message2 字符串和一个 sendGradpaMessage 方法。

sendGradpaMessage 方法用于接收子组件传递的消息。

// grandpa.vue



爷组件




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
parent.vue 组件(父)

使用 inject 方法注入了从爷组件提供的 message 参数。
// parent.vue



父组件


{ { message }}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
son.vue 组件(子)

使用 inject 方法注入了从爷组件提供的 message2 字符串和一个 sendGradpaMessage 方法。

当点击按钮时,调用 sendGradpaMessage 方法将消息传递给祖先组件。

// son.vue



孙组件


{ { message2 }}
发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
上述示例中:

grandpa.vue 组件通过 provide 方法提供了 message, message2 两个参数和一个名为 sendGradpaMessage 的方法。

parent.vue 组件通过 inject 接收了 message 参数,并在模板中使用 message。

son.vue 组件通过 inject 接收了 message2 参数,并在模板中使用 message,同时通过点击按钮触发 sendGradpaMessage 方法将参数 msg 传给了 grandpa.vue 组件。

类型检查
inject 的配置项可以是一个数组或者一个对象。当使用对象形式时,可以指定更多的配置选项,比如类型检查、默认值等。

配置选项详解

from:指定 inject 要注入的数据的键名。如果没有指定,则默认为 inject 的键名。

default:如果没有从祖先组件中找到对应的数据,则使用这个默认值。这对于确保组件即使在缺少某些数据的情况下也能正常工作是非常有用的。

from 和 default 的组合:你可以同时指定 from 和 default,在这种情况下,如果 from 指定的数据不存在,则使用 default 中定义的值。

例如,你可以指定默认值和别名:

inject: {
// 定义别名为 message2 的数据,其来源为 message2
message2: {
from: 'message2',
// 如果没有提供则使用默认值
default: 'Default value if not provided'
},
// 定义别名为 sendGradpaMessage 的方法
sendGradpaMessage: {
from: 'sendGradpaMessage',
// 如果没有提供则使用一个空函数作为默认值
default: () => {}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vue3.x 使用
在 Vue 3.x 中,provide 和 inject 的使用方式有所变化,主要是因为引入了 Composition API。在 Composition API 中,provide 和 inject 的使用更加灵活,并且通常在 setup 函数中进行操作。

注意事项:

  1. Composition API 中的使用:

在 Vue 3.x 中,provide 和 inject 必须在 setup 函数中使用。

provide 通常用来向子组件提供数据或方法。

inject 用来从父组件或其他祖先组件获取数据或方法。

  1. 响应式处理:

当使用 provide 提供一个响应式对象时,Vue 3.x 会自动处理它的响应性。然而,如果提供的数据不是响应式的,那么注入的数据也不会是响应式的。

  1. 类型安全:

在 TypeScript 项目中,可以使用类型注解来确保 provide 和 inject 的类型安全。

  1. 默认值:

在 Vue 3.x 中,inject 可以接受一个默认值作为第二个参数,如果找不到对应的 provide 数据,则使用默认值。

  1. 调试:

使用 provide 和 inject 时,确保在开发过程中使用 Vue Devtools 来帮助跟踪数据流。
示例
grandpa.vue 组件(爷)

使用 provide 方法提供了 message, message2 字符串和一个 sendGradpaMessage 方法。

sendGradpaMessage 方法用于接收子组件传递的消息。

// grandpa.vue



爷组件


{ { num1 }}




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
parent.vue 组件(父)

使用 inject 方法注入了从爷组件提供的 message2 参数。
// parent.vue



父组件


{ { message2 }}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
son.vue 组件(子)

使用 inject 方法注入了从爷组件提供的 message2 字符串和一个 sendGradpaMessage 方法。

当点击按钮时,调用 sendGradpaMessage 方法将消息传递给祖先组件。

// son.vue



孙组件


{ { message }}

发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
上述示例中:

grandpa.vue 组件通过 provide 方法提供了 message, message2 两个参数和一个名为 sendGradpaMessage 的方法。

parent.vue 组件通过 inject 接收了 message 参数,并在模板中使用 message。

son.vue 组件通过 inject 接收了 message2 参数,并在模板中使用 message,同时通过点击按钮触发 sendGradpaMessage 方法将参数 msg 传给了 grandpa.vue 组件。

总结
provide 和 inject 是 Vue.js 中一种用于跨越多个层级组件间通信的机制,通过在组件中定义 provide 方法提供数据或方法,并在其他组件中使用 inject 方法注入这些数据或方法,从而简化了多层级组件间的通信。这种方式不仅减少了逐层传递 props 的代码量,提高了代码的可读性和可维护性,还支持动态提供和注入数据,适用于多种场景。然而,过度使用 provide 和 inject可能会导致组件之间的耦合度增加,影响代码的调试和维护。

相关文章
|
JavaScript 前端开发
javascript数组对象根据id去重的四种方法
Js代码组织结构良好一般都呈现以下五个特点:始终声明我们的依赖、为第三方代码库添加shim(垫片)、定义跟调用应该分离、依赖应该异步加载、模块不应依赖全局变量。
1560 0
Vue3 跨组件传参 provide 与 inject
Vue3 跨组件传参 provide 与 inject
191 0
|
JavaScript 前端开发
JS之url进行编码和解码(三种方式)
JS之url进行编码和解码(三种方式)
19822 2
|
Ubuntu Shell Python
Ubuntu学习笔记(一):pycharm设置快捷启动图标详解
这篇博客详细讲解了如何在Ubuntu 20.04系统中为PyCharm设置快捷启动图标,包括创建.desktop文件、编辑文件内容以及添加到收藏夹的步骤。
992 0
Ubuntu学习笔记(一):pycharm设置快捷启动图标详解
|
API
Vue3组件通信全解析:利用props、emit、provide/inject跨层级传递数据,expose与ref实现父子组件方法调用
Vue3组件通信全解析:利用props、emit、provide/inject跨层级传递数据,expose与ref实现父子组件方法调用
3203 0
|
8月前
|
JavaScript 前端开发
开发和内网部署正常,反向代理后出现404和图片加载失败的解决方案;部署到公网后报错404;部署到公网后图片加载出错;动态渲染获取图片失败
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
存储 前端开发 Java
Element el-upload 文件上传/图片上传/拖拽上传/附带参数/附带请求头部详解
文目录 1. 前言 2. 基本用法 2.1 前端部分 2.2 后端部分 2.3 获取后端返回信息 3. 外观功能介绍 3.1 拖拽上传 3.2 显示图片 3.3 设置文件列表样式 3.4 显示提示信息 4. 事件功能介绍 4.1 限制上传文件数量 4.2 限制上传文件类型和大小 4.3 移除文件处理 4.4 手动上传 5. 附带参数 6. 附带请求头部 7. 小结
7473 0
|
前端开发 JavaScript
vue+el-select下拉多选实现,全选,反选,清空功能源码
vue+el-select下拉多选实现,全选,反选,清空功能源码
761 0
|
JavaScript 算法
【Vue面试题十七】、你知道vue中key的原理吗?说说你对它的理解
这篇文章深入探讨了Vue中`key`的原理及其作用,解释了`key`是为每个虚拟DOM节点提供的唯一标识符,作为`diff`算法的优化策略,有助于更快速准确地识别和重用DOM元素。文章通过实际代码示例展示了使用`key`与否在列表渲染时对DOM操作的影响,分析了`key`在不同场景下的性能表现,并提供了源码层面的分析,解释了Vue如何通过`key`来识别和更新虚拟DOM节点。
【Vue面试题十七】、你知道vue中key的原理吗?说说你对它的理解
|
JSON JavaScript 定位技术
Echarts 绘制地图(中国、省市、区县),保姆级教程!
Echarts 绘制地图(中国、省市、区县),保姆级教程!