组件通信——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};
}
- 附加到组件实例: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<template><div class="grandpa"><h2>爷组件</h2><parent /></div>
</template><script>
import parent from './parent.vue';export default {name: 'grandpa',data() {return {}},provide() {return {message: 'This is some shared data1',message2: 'This is some shared data2',sendGradpaMessage: this.getSendMessage};},components: {parent},methods: {getSendMessage(message) {console.log('Message received:', message);}}
}
</script>
parent.vue 组件(父)
- 使用
inject
方法注入了从爷组件提供的message
参数。
// parent.vue<template><div class="parent"><h2>父组件</h2><span>{{ message }}</span><son /></div>
</template><script>
import son from './son.vue';export default {name: 'parent',data() {return {}},inject: ['message'],components: { son },methods: {}
}
</script>
son.vue 组件(子)
-
使用
inject
方法注入了从爷组件提供的message2
字符串和一个sendGradpaMessage
方法。 -
当点击按钮时,调用
sendGradpaMessage
方法将消息传递给祖先组件。
// son.vue<template><div class="son"><h2>孙组件</h2><span>{{ message2 }}</span><el-button type="primary" @click="sendMessage">发送消息</el-button></div>
</template><script>
export default {name: 'son',data() {return {}},inject: ['message2', 'sendGradpaMessage'],methods: {sendMessage() {const msg = 'Hello from son component!';this.sendGradpaMessage(msg);}}
}
</script>
上述示例中:
-
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 的数据,其来源为 message2message2: { from: 'message2',// 如果没有提供则使用默认值default: 'Default value if not provided'},// 定义别名为 sendGradpaMessage 的方法sendGradpaMessage: {from: 'sendGradpaMessage',// 如果没有提供则使用一个空函数作为默认值default: () => {}}
}
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 用来从父组件或其他祖先组件获取数据或方法。
2. 响应式处理:
- 当使用 provide 提供一个响应式对象时,Vue 3.x 会自动处理它的响应性。然而,如果提供的数据不是响应式的,那么注入的数据也不会是响应式的。
3. 类型安全:
- 在 TypeScript 项目中,可以使用类型注解来确保 provide 和 inject 的类型安全。
4. 默认值:
- 在 Vue 3.x 中,inject 可以接受一个默认值作为第二个参数,如果找不到对应的 provide 数据,则使用默认值。
5. 调试:
- 使用 provide 和 inject 时,确保在开发过程中使用 Vue Devtools 来帮助跟踪数据流。
示例
grandpa.vue 组件(爷)
-
使用
provide
方法提供了message
,message2
字符串和一个sendGradpaMessage
方法。 -
sendGradpaMessage 方法用于接收子组件传递的消息。
// grandpa.vue<template><div class="grandpa"><h2>爷组件</h2><div>{{ num1 }}</div><parent /></div>
</template><script setup lang="ts" name="grandpa">
import { provide, ref } from 'vue';import parent from './parent.vue';// 定义一个可变的值
const message = ref('Hello from grandpa');
const message2 = ref('Hello from Parent');let num1 = ref(0);
// 使用 provide 将这个值暴露给子组件
provide('message', message);
provide('message2', message2);
provide('sendGradpaMessage', getSendMessage);// 接受 son 组件传递的参数
function getSendMessage(num: number) {console.log('msg::: ', num);num1.value = num
}
</script>
parent.vue 组件(父)
- 使用
inject
方法注入了从爷组件提供的message2
参数。
// parent.vue<template><div class="parent"><h2>父组件</h2><span>{{ message2 }}</span><son /></div>
</template><script setup lang="ts" name="parent">
import son from './son.vue';
import { inject, onMounted } from 'vue';// 使用 inject 获取父组件提供的值
const message2 = inject('message2');
</script>
son.vue 组件(子)
-
使用
inject
方法注入了从爷组件提供的message2
字符串和一个sendGradpaMessage
方法。 -
当点击按钮时,调用
sendGradpaMessage
方法将消息传递给祖先组件。
// son.vue<template><div class="son"><h2>孙组件</h2><div>{{ message }}</div><el-button type="primary" @click="sendMessage(111)">发送消息</el-button></div>
</template><script setup lang="ts" name="son">import { inject, onMounted } from 'vue';// 使用 inject 获取父组件提供的值
const message = inject('message', '默认值');const sendMessage = inject('sendGradpaMessage', (params: number) => { });</script>
上述示例中:
-
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
可能会导致组件之间的耦合度增加,影响代码的调试和维护。
相关文章:
组件通信——provide 和 inject 实现爷孙组件通信
provide 和 inject 实现爷孙组件通信 介绍 provide 和 inject 是 Vue.js 提供的一种在组件之间共享数据的机制,它允许在组件树中的任何地方注入依赖项。这对于跨越多个层级的组件间通信特别有用,因此无需手动将 prop 数据逐层传递下去。 provide&#…...
【ShuQiHere】探索人工智能核心:机器学习的奥秘
【ShuQiHere】 💡 什么是机器学习? 机器学习(Machine Learning, ML)是人工智能(Artificial Intelligence, AI)中最关键的组成部分之一。它使得计算机不仅能够处理数据,还能从数据中学习&#x…...
LeeCode打卡第二十四天
LeeCode打卡第二十四天 第一题:对称二叉树(LeeCode第101题): 给你一个二叉树的根节点 root , 检查它是否轴对称。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* …...

什么是科技与艺术相结合的异形创意圆形(饼/盘)LED显示屏
在当今数字化与创意并重的时代,科技与艺术的融合已成为推动社会进步与文化创新的重要力量。其中,晶锐创显异形创意圆形LED显示屏作为这一趋势下的杰出代表,不仅打破了传统显示设备的形态束缚,更以其独特的造型、卓越的显示效果和广…...

AI大模型知识点大梳理_ai大模型知识学习,零基础入门到精通,收藏这一篇就够了
文章目录 AI大模型是什么AI大模型发展历程AI大模型的底层原理AI大模型解决的问题大模型的优点和不足影响个人观点 AI大模型是什么 AI大模型是指具有巨大参数量的深度学习模型,通常包含数十亿甚至数万亿个参数。这些模型可以通过学习大量的数据来提高预测能力&…...

NVG040W语音芯片:为制氧机带来个性化语音提示和报警功能
在当今社会,家庭医疗设备和健康保健产品越来越受到人们的关注。制氧机作为其中的一种,为许多需要氧气治疗的人们提供了重要的帮助。然而,对于许多用户来说,如何正确操作和维护这些设备仍然是一个挑战。为此,NVG040W语音…...

OpenCV结构分析与形状描述符(12)椭圆拟合函数fitEllipseAMS()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆拟合一组2D点。它返回一个内切于该椭圆的旋转矩形。使用了由[260]提出的近…...
安卓显示驱动
安卓显示驱动是用于在Android设备上提供图形和视频显示的底层软件组件。 显示驱动在Android系统中扮演着至关重要的角色,它们负责将图形和视频内容从系统内存传输到显示屏上。这些驱动程序确保了用户界面、图像、视频和游戏等视觉元素的正常显示。以下是关于安卓显…...

java重点学习-集合(List)
七 集合(List) 7.1 复杂度分析 7.2 数组 1.数组(Array)是一种用连续的内存空间存储相同数据类型 数据的线性数据结构。 2.数组下标为什么从0开始 寻址公式是:baseAddressi*dataTypeSize,计算下标的内存地址效率较高 3.查找的时间复杂度 随机(…...

【PCB测试】最常见的PCB测试方法
系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 一、PCB测试的好处1.发现错误2.降低成本3.节省时间4.减少退货率5.提高安全性 二、PCB测试内容1.孔壁质量2.电镀铜3.清…...
AtCoder Beginner Contest 370 ABCD题详细题解(C++,Python)
前言: 本文为AtCoder Beginner Contest 370 ABCD题的详细题解,包含C,Python语言描述,觉得有帮助或者写的不错可以点个赞 个人感觉D比C简单,C那里的字典序有点不理解, E应该是前缀和加dp,但是是dp不明白,等我明白了会更…...
斯坦福研究人员探讨大型语言模型在社交网络生成中的应用及其在政治同质性上的偏见
社交网络生成在许多领域有着广泛的应用,比如流行病建模、社交媒体模拟以及理解社交现象如两极化等。当由于隐私问题或其他限制无法直接观察真实网络时,创建逼真的社交网络就显得尤为重要。这些生成的网络对于在这些情况下准确建模互动和预测结果至关重要…...

一招教你找到Facebook广告的最佳发帖时间
在社交媒体上做广告时,时机是至关重要的。有时候你投放的广告参与度低,很有可能是因为你没有在适当的时机投放广告。这篇文章会教你如何找到适合自己的广告投放时间,如果你感兴趣的话,就继续看下去吧! 首先࿰…...

【数据库】MySQL-基础篇-多表查询
专栏文章索引:数据库 有问题可私聊:QQ:3375119339 目录 一、多表关系 1.一对多 2.多对多 3.一对一 二、多表查询概述 1.数据准备 2.概述 3.分类 三、内连接 1.隐式内连接 2.显式内连接 3.案例 四、外连接 1.左外连接 2.右外连…...

MongoDB事务机制
事务机制 1.事务概念 在对数据的操作的过程中,涉及到一连串的操作,这些操作如果失败,会导致我们的数据部分变化了,部分没变化。这个过程就好比如你去吃早餐,你点完餐了,并且吃完早餐了,没付钱你…...

大模型 LLM(Large Language Models)如今十分火爆,对于初入此领域的新人小白来说,应该如何入门 LLM 呢?是否有值得推荐的入门教程呢?
前言 很明显,这是一个偏学术方向的指南要求,所以我会把整个LLM应用的从数学到编程语言,从框架到常用模型的学习方法,给你捋一个通透。也可能是不爱学习的劝退文。 通常要达到熟练的进行LLM相关的学术研究与开发,至少…...
Python实现模糊逻辑算法
博客目录 引言 什么是模糊逻辑?模糊逻辑的应用场景模糊逻辑的基本思想 模糊逻辑的原理 模糊集合与隶属函数模糊推理系统(FIS)模糊规则和推理过程 Python实现模糊逻辑算法 面向对象的设计思路代码实现示例与解释 模糊逻辑算法应用实例&…...

MATLAB、FPGA、STM32中调用FFT计算频率、幅值及相位差
系列文章目录 文章目录 系列文章目录前言MATLABSTM32调用DSPSTM32中实现FFT关于初相位 FPGA 前言 最近在学习如何在STM32中调用FFT MATLAB 首先对FFT进行一下说明,我们输入N个点的数据到FFT中,FFT会返回N个点的数据,这些数据都是复数&#…...

基于SSM的医院药品库存系统的设计与实现---附源码76620
摘要 医院药品库存管理是医院管理的重要组成部分,对于保障医疗服务的质量和效率具有重要意义。传统的手工管理方式已经无法满足药品库存管理的需求,因此建立一个医院药品库存系统具有重要的实践价值。 使用Java语言开发医院药品库存系统可以兼容不同操作…...
Jupyter管理内核命令
1.显示有哪些内核 jupyter kernelspec list2.删除某个内核 jupyter kernelspec remove xxx3.添加某个内核 先激活环境 conda activate test_env然后安装ipykernel包 pip install ipykernel在虚拟环境中安装ipykernel包 python -m ipykernel install --name test_env安装过…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...