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

Vue3-跨层组件通信Provide/Inject机制详解

Vue 3 中的 ProvideInject 机制是专为跨层级传递数据而设计的,适用于祖先组件和后代组件之间的通信。与propsemits 不同,Provide/Inject 可以跨越多个层级进行数据传递,而不需要逐层传递。

1. Provide

provide 是一个在祖先组件中提供数据的方法,它将数据传递给该组件的所有后代组件(不需要直接的父子关系)。provide 通常在组件的 setup 函数中使用。

2. Inject

inject 是在后代组件中获取祖先组件提供的数据的方法。inject 也是在 setup 函数中使用,后代组件通过 inject 来访问祖先组件的 provide 数据。

基本使用

步骤 1:在祖先组件中使用 provide 提供数据

祖先组件通过 provide 将数据提供给后代组件。

// Parent.vue
<template><Child />
</template><script>
import { provide } from 'vue';
import Child from './Child.vue';export default {components: { Child },setup() {// 提供数据const message = "Hello from Parent!";provide('message', message);  // 'message' 是标识符,message 是提供的值}
};
</script>

在上面的例子中,Parent 组件通过 provide 提供了一个名为 message 的数据,值是字符串 "Hello from Parent!"。任何后代组件都可以通过 inject 来访问这个数据。

步骤 2:在后代组件中使用 inject 获取数据

后代组件通过 inject 来访问祖先组件提供的数据。

// Child.vue
<template><div>{{ message }}</div>
</template><script>
import { inject } from 'vue';export default {setup() {const message = inject('message');  // 使用 inject 获取数据return { message };}
};
</script>

在上面的代码中,Child 组件通过 inject 获取祖先组件 Parent 提供的 message 数据,并将其渲染在模板中。

如何通过后代组件修改上级组件的值

在 Vue 中,provide 传递的数据是响应式的,但它只提供了只读数据。若要让后代组件修改上级组件的数据,可以通过 provide 传递一个可变的对象或函数来实现。这也可以用来在后代组件中修改祖先组件的状态。

1. 传递响应式数据

你可以通过 reactiveref 将响应式数据传递给后代组件,这样后代组件就可以通过修改响应式数据来更改祖先组件的状态。

// Parent.vue
<template><Child /><div>{{ message.text }}</div> <!-- 显示修改后的数据 -->
</template><script>
import { reactive, provide } from 'vue';
import Child from './Child.vue';export default {components: { Child },setup() {// 提供响应式对象const message = reactive({ text: "Hello from Parent!" });provide('message', message);  // 提供响应式对象return { message };}
};
</script>

Parent 组件中,使用 reactive 创建了一个响应式对象 message,并通过 provide 提供给后代组件。接下来,后代组件就可以修改这个对象的内容。

2. 在后代组件中修改响应式数据

后代组件可以直接修改由 provide 提供的响应式对象的数据, 因为这违背了组件通信中单向数据流的规范,所以不推荐直接在后代组件中直接修改来自上级数据的值。

// Child.vue
<template><button @click="changeMessage">Change Message</button>
</template><script>
import { inject } from 'vue';export default {setup() {const message = inject('message');  // 获取祖先组件提供的响应式对象// 修改 message 对象中的值const changeMessage = () => {message.text = "Updated message from Child!";};return { message, changeMessage };}
};
</script>

Child 组件中,通过 inject 获取祖先组件提供的响应式对象 message,并提供一个方法 changeMessage 来修改 message.text。由于 message 是响应式的,修改后会自动更新祖先组件中的视图。

通过函数传递数据

除了传递响应式对象外,另一个常见的方法是传递修改数据的函数。这样可以控制后代组件如何修改上级组件的值。

1. 祖先组件传递函数
// Parent.vue
<template><Child /><div>{{ message }}</div>  <!-- 显示修改后的数据 -->
</template><script>
import { ref, provide } from 'vue';
import Child from './Child.vue';export default {components: { Child },setup() {const message = ref("Hello from Parent!");// 提供修改数据的函数const changeMessage = (newMessage) => {message.value = newMessage;};provide('changeMessage', changeMessage);  // 提供修改函数return { message };}
};
</script>

Parent 组件中,我们通过 provide 提供了一个函数 changeMessage,它接收一个新的消息并修改 message 的值。

2. 后代组件调用函数修改数据
// Child.vue
<template><button @click="changeParentMessage">Change Parent Message</button>
</template><script>
import { inject } from 'vue';export default {setup() {const changeMessage = inject('changeMessage');  // 获取修改数据的函数// 调用函数修改父组件的值const changeParentMessage = () => {changeMessage("Message updated from Child!");};return { changeParentMessage };}
};
</script>

Child 组件中,通过 inject 获取 changeMessage 函数,并在按钮点击时调用它来修改父组件的 message

总结

  • provide:在祖先组件中提供数据,供后代组件使用。
  • inject:在后代组件中接收祖先组件提供的数据。
  • 响应式数据传递:你可以传递响应式数据对象(如 reactiveref),使得后代组件修改这些数据会反映到祖先组件。
  • 函数传递:通过提供修改函数,后代组件可以控制数据的修改,从而影响祖先组件的状态。

Provide/Inject 机制非常适合跨越多个层级的组件通信,并且能够避免通过多层级的 props 传递,减少了组件间的耦合度。

相关文章:

Vue3-跨层组件通信Provide/Inject机制详解

Vue 3 中的 Provide 和 Inject 机制是专为跨层级传递数据而设计的&#xff0c;适用于祖先组件和后代组件之间的通信。与props 和 emits 不同&#xff0c;Provide/Inject 可以跨越多个层级进行数据传递&#xff0c;而不需要逐层传递。 1. Provide provide 是一个在祖先组件中提…...

Linux Jar包定时重启脚本,按最新时间的Jar包启动

Linux Jar包定时重启脚本,按最新时间的Jar包启动 jar包按时间顺序命名如下: park-system-1.1.0-SNAPSHOT_20210101.jar park-system-1.1.0-SNAPSHOT_20210402.jar park-system-1.1.0-SNAPSHOT_20220520.jar 则该脚本默认启动时间最大的一个:park-system-1.1.0-SNAPSHOT_2022…...

HTML5实现好看的博客网站、通用大作业网页模板源码

HTML5实现好看的博客网站、通用大作业网页模板源码 前言一、设计来源1.1 主界面1.2 列表界面1.3 文章界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的博客网站、通用大作业网页模板源码&#xff0c;博客网站源码&#xff0c;HTML模板源码&#xff0…...

掌握RabbitMQ:全面知识点汇总与实践指南

前言 RabbitMQ 是基于 AMQP 高级消息队列协议的消息队列技术。 特点&#xff1a;它通过发布/订阅模型&#xff0c;实现了服务间的高度解耦。因为消费者不需要确保提供者的存在。 作用&#xff1a;服务间异步通信&#xff1b;顺序消费&#xff1b;定时任务&#xff1b;请求削…...

go如何从入门进阶到高级

针对Go语言的学习&#xff0c;不同阶段应采取不同的学习方式&#xff0c;以达到最佳效果.本文将Go的学习分为入门、实战、进阶三个阶段&#xff0c;下面分别详细介绍 一、社区 Go语言中文网 作为专注于Go语言学习与推广的平台&#xff0c;Go语言中文网为开发者提供了丰富的中…...

在环境冲突情况下调整优先级以解决ROS Catkin构建中缺少模块的问题【ubuntu20.04】

在机器人操作系统&#xff08;ROS&#xff09;的开发过程中&#xff0c;构建工作空间时遇到各种依赖性问题是常见的挑战之一。尤其是在多Python环境共存的情况下&#xff0c;环境变量的冲突往往导致诸如缺少empy模块等错误。本文将详细介绍在ROS Noetic与Anaconda Python环境共…...

github 个人主页配置

Guthub 个人主页 &#xff08;官方称呼是 profile&#xff09;可以展示很多有用的信息&#xff0c;例如添加一个首页被访问次数的计数器&#xff0c;一个被 Star 与 Commit 的概览信息&#xff0c;以及各种技能标签&#xff0c;设备标签等&#xff0c;还可以利用 wakatime 显示…...

STM32-笔记30-编程实现esp8266联网功能

串口2连接ESP8266模块 复制项目文件34-ESP8266串口间的通信 重命名为35-编程实现ESP8266联网功能 打开项目文件 main.c #include "sys.h" #include "delay.h" #include "led.h" #include "uart1.h" #include "esp8266.h"…...

oscp备考 oscp系列——Kioptix Level 1靶场 古老的 Apache Vuln

目录 前言 1. 主机发现 2. 端口扫描 3. 指纹识别 4. 目录扫描 5. 漏洞搜索和利用 前言 oscp备考&#xff0c;oscp系列——Kioptix Level 1靶场 Kioptix Level 1难度为简单靶场&#xff0c;主要考察 nmap的使用已经是否会看输出&#xff0c;以及是否会通过应用查找对应漏…...

《机器学习》——随机森林

文章目录 什么是随机森林&#xff1f;随机森林的原理随机森林的优缺点优点缺点 随机森林模型API主要参数 实例实例步骤导入数据处理数据&#xff0c;切分数据构建模型训练模型测试数据并输出分类报告和混淆矩阵画出模型的前十重要性的特征 扩展 什么是随机森林&#xff1f; -随…...

指代消解:自然语言处理中的核心任务与技术进展

目录 前言1. 指代消解的基本概念与分类1.1 回指与共指 2. 指代消解的技术方法2.1 端到端指代消解2.2 高阶推理模型2.3 基于BERT的模型 3. 事件共指消解&#xff1a;跨文档的挑战与进展3.1 联合模型3.2 语义嵌入模型&#xff08;EPASE&#xff09; 4. 应用场景与前景展望4.1 关键…...

记录一下Unity webgl cannot read properties of undefined reading apply 错误

出现这个问题说明你Build 文件夹的内容和最新的打包内容冲突了 解决方法是把Build文件夹里面的东西全部删了 然后使用Unity重新生成这些文件 后续发现还是有这个问题 然后想了一下本地冲突应该在前端吧本地的文件删了重新拉取服务器的文件才行 以下是解决方法 <script t…...

【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1. 选择结构基本概念 2. 主要语句类型​&#xff08;if、if-else、switch&#xff09; 3. 跃迁函数中变量的取值范围 4. 计算阶跃函数的值 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;输入x的值&#x…...

unity 播放 序列帧图片 动画

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、方法一&#xff1a;代码控制播放序列帧1、设置图片属性2、创建Image组件3、简单的代码控制4、挂载代码并赋值 二、方法二&#xff1a;直接使用1.Image上添加…...

HTML - <a>

目录 1.简介 2.属性 2.1 href 2.2 hreflang 2.3 title 2.4 target 2.5 rel 2.6 referrerpolicy 2.7 ping 2.8 type 2.9 download 3.邮件链接 4.电话链接 1.简介 链接&#xff08;hyperlink&#xff09;是互联网的核心。它允许用户在页面上&#xff0c;从一个网址…...

Unity学习笔记(六)使用状态机重构角色移动、跳跃、冲刺

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 整体状态框架(简化) Player 是操作对象的类&#xff1a; 继承了 MonoBehaviour 用于定义游戏对象的行为&#xff0c;每个挂载在 Unity 游戏对象上的脚本都需要继承自 MonoBehaviour&#x…...

【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】

目录&#x1f60b; 任务描述 相关知识 1. 二叉树的基本概念与结构定义 2. 建立二叉树 3. 先序遍历 4. 中序遍历 5. 后序遍历 6. 层次遍历 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;实现二叉树的遍历 相关知识 为了完成本关任务&#xff0c;你需要掌…...

Android Telephony | 协议测试针对 test SIM attach network 的问题解决(3GPP TS 36523-1-i60)

背景 除了运营商实网卡之外,在各种lab的协议测试中需要 follow 3GPP 协议定义(可以查询3gpp.org website 获取),那么 feature 需要支持覆盖的卡就不止运营商本身了。 本文介绍 IA APN流程,重点关注在协议/lab测试中,针对测试卡、非实网卡的的设置项,记录遇到的问题分…...

jenkins入门3 --执行一个小demo

1、新建视图 视图可以理解为是item的集合&#xff0c;这样可以将item分类。新建视频可以选择加入已有的item 2、新建item 1)输入任务名称、选择一个类型&#xff0c;常用的是第一个freestyle project 2&#xff09;进行item相关配置&#xff0c;general 设置项目名字,描述,参数…...

STM32传感器系列:GPS定位模块

简介 我们在做一些项目的时候&#xff0c;可能需要使用到GPS模块&#xff0c;我们可以通过这个模块获得当前的位置以及时间&#xff0c;我这里就教大家如何去使用GPS定位模块&#xff0c;并且把示例代码开源到评论区下面&#xff0c;有需要自取即可&#xff0c;我我这里用到的…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...