当前位置: 首页 > news >正文

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

provide 和 inject 实现爷孙组件通信

介绍

provideinject 是 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 的代码量,提高了代码的可读性和可维护性。

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

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

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

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

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

  • fromdefault 的组合:你可以同时指定 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 中,provideinject 的使用方式有所变化,主要是因为引入了 Composition API。在 Composition API 中,provideinject 的使用更加灵活,并且通常在 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 组件。

总结

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

相关文章:

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

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

【ShuQiHere】探索人工智能核心:机器学习的奥秘

【ShuQiHere】 &#x1f4a1; 什么是机器学习&#xff1f; 机器学习&#xff08;Machine Learning, ML&#xff09;是人工智能&#xff08;Artificial Intelligence, AI&#xff09;中最关键的组成部分之一。它使得计算机不仅能够处理数据&#xff0c;还能从数据中学习&#x…...

LeeCode打卡第二十四天

LeeCode打卡第二十四天 第一题&#xff1a;对称二叉树&#xff08;LeeCode第101题&#xff09;: 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* …...

什么是科技与艺术相结合的异形创意圆形(饼/盘)LED显示屏

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

AI大模型知识点大梳理_ai大模型知识学习,零基础入门到精通,收藏这一篇就够了

文章目录 AI大模型是什么AI大模型发展历程AI大模型的底层原理AI大模型解决的问题大模型的优点和不足影响个人观点 AI大模型是什么 AI大模型是指具有巨大参数量的深度学习模型&#xff0c;通常包含数十亿甚至数万亿个参数。这些模型可以通过学习大量的数据来提高预测能力&…...

NVG040W语音芯片:为制氧机带来个性化语音提示和报警功能

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

OpenCV结构分析与形状描述符(12)椭圆拟合函数fitEllipseAMS()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆&#xff0c;该椭圆拟合一组2D点。它返回一个内切于该椭圆的旋转矩形。使用了由[260]提出的近…...

安卓显示驱动

安卓显示驱动是用于在Android设备上提供图形和视频显示的底层软件组件。 显示驱动在Android系统中扮演着至关重要的角色&#xff0c;它们负责将图形和视频内容从系统内存传输到显示屏上。这些驱动程序确保了用户界面、图像、视频和游戏等视觉元素的正常显示。以下是关于安卓显…...

java重点学习-集合(List)

七 集合&#xff08;List&#xff09; 7.1 复杂度分析 7.2 数组 1.数组(Array)是一种用连续的内存空间存储相同数据类型 数据的线性数据结构。 2.数组下标为什么从0开始 寻址公式是:baseAddressi*dataTypeSize&#xff0c;计算下标的内存地址效率较高 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题的详细题解&#xff0c;包含C,Python语言描述&#xff0c;觉得有帮助或者写的不错可以点个赞 个人感觉D比C简单&#xff0c;C那里的字典序有点不理解, E应该是前缀和加dp&#xff0c;但是是dp不明白&#xff0c;等我明白了会更…...

斯坦福研究人员探讨大型语言模型在社交网络生成中的应用及其在政治同质性上的偏见

社交网络生成在许多领域有着广泛的应用&#xff0c;比如流行病建模、社交媒体模拟以及理解社交现象如两极化等。当由于隐私问题或其他限制无法直接观察真实网络时&#xff0c;创建逼真的社交网络就显得尤为重要。这些生成的网络对于在这些情况下准确建模互动和预测结果至关重要…...

一招教你找到Facebook广告的最佳发帖时间

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

【数据库】MySQL-基础篇-多表查询

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

MongoDB事务机制

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

大模型 LLM(Large Language Models)如今十分火爆,对于初入此领域的新人小白来说,应该如何入门 LLM 呢?是否有值得推荐的入门教程呢?

前言 很明显&#xff0c;这是一个偏学术方向的指南要求&#xff0c;所以我会把整个LLM应用的从数学到编程语言&#xff0c;从框架到常用模型的学习方法&#xff0c;给你捋一个通透。也可能是不爱学习的劝退文。 通常要达到熟练的进行LLM相关的学术研究与开发&#xff0c;至少…...

Python实现模糊逻辑算法

博客目录 引言 什么是模糊逻辑&#xff1f;模糊逻辑的应用场景模糊逻辑的基本思想 模糊逻辑的原理 模糊集合与隶属函数模糊推理系统&#xff08;FIS&#xff09;模糊规则和推理过程 Python实现模糊逻辑算法 面向对象的设计思路代码实现示例与解释 模糊逻辑算法应用实例&…...

MATLAB、FPGA、STM32中调用FFT计算频率、幅值及相位差

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

基于SSM的医院药品库存系统的设计与实现---附源码76620

摘要 医院药品库存管理是医院管理的重要组成部分&#xff0c;对于保障医疗服务的质量和效率具有重要意义。传统的手工管理方式已经无法满足药品库存管理的需求&#xff0c;因此建立一个医院药品库存系统具有重要的实践价值。 使用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安装过…...

简单分享-获取.txt文件内数据 文件内数据逗号分隔 分隔符 C语言

简单分享-获取.txt文件内数据 文件内数据逗号分隔 分隔符 C语言 数据存储到文件中&#xff0c;把文件数据读取到数组&#xff0c;方便数据处理。 # include <stdio.h> # include <stdlib.h> # include <string.h>#define DATANUM 307200 //数组个数 int ma…...

从0开始手把手带你入门Vue3

前言 本文并非标题党&#xff0c;而是实实在在的硬核文章&#xff0c;如果有想要学习Vue3的网友&#xff0c;可以大致的浏览一下本文&#xff0c;总体来说本篇博客涵盖了Vue3中绝大部分内容&#xff0c;包含常用的CompositionAPI(组合式API)、其它CompositionAPI以及一些新的特…...

C# USB通信技术(通过LibUsbDotNet库)

文章目录 1.下载LibusbDotNet库2.引入命名空间3. 实例化USB设备4.发送数据5.关闭连接 1.下载LibusbDotNet库 右击项目选择管理NuGet程序包在弹出的界面中搜索LibusbDotNet&#xff0c;然后下载安装。 2.引入命名空间 using LibUsbDotNet; using LibUsbDotNet.Main;3. 实例化…...

常用Java API

1 字符串处理 1.1 String 类 String 类是 Java 中不可变的字符序列。它提供了以下常用方法&#xff1a; length()&#xff1a;返回字符串的长度。 charAt(index)&#xff1a;返回指定索引处的字符。 substring(startIndex, endIndex)&#xff1a;返回从 startIndex 到 endI…...

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化&#xff0c;使其看起来更清晰&#xff0c;同时保持尺寸不变&#xff0c;通常涉及到图像处理技术如锐化、降噪、对比度增强…...

Java 回顾方法的定义

一、方法的定义 1&#xff0e;修饰符&#xff08;public static…&#xff09;详见博客【Java 方法的定义】 2&#xff0e;返回值&#xff08;int, double, char[],…., void&#xff09;详见博客【Java 方法的定义】 3. break&#xff1a;跳出switch 结束循环&#xff0c;详…...

网络安全产品认证证书大全(持续更新...)

文章目录 一、引言二、《计算机信息系统安全专用产品销售许可证》2.1 背景2.2 法律法规依据2.3 检测机构2.4 检测依据2.5 认证流程2.6 证书样本 三、《网络关键设备和网络安全专用产品安全认证证书》3.1 背景3.2 法律法规依据3.3 检测机构3.4安全认证和安全检测依据标准3.5 认证…...

win10 安装多个版本的python

1&#xff0c;安装python3.9 和python3.10 2, 安装完之后分别打开两个版本的Python的安装目录&#xff08;第一层目录&#xff09;&#xff0c;把pythonw.exe分别重命名为pythonw_39.exe和pythonw_310.exe&#xff0c;把python.exe复制一份&#xff0c;并分别重命名为python_…...

【ORACLE】数据备份

Oracle数据库备份是确保数据安全和可靠性的重要环节。Oracle提供了多种备份方法&#xff0c;包括冷备份、热备份、逻辑备份&#xff08;如使用expdp和impdp&#xff09;以及使用RMAN&#xff08;Recovery Manager&#xff09;进行物理备份。 冷备份&#xff1a;在数据库关闭的状…...

[Golang] goroutine

[Golang] goroutine 文章目录 [Golang] goroutine并发进程和线程协程 goroutine概述如何使用goroutine 并发 进程和线程 谈到并发&#xff0c;大多都离不开进程和线程&#xff0c;什么是进程、什么是线程&#xff1f; 进程可以这样理解&#xff1a;进程就是运行着的程序&…...