Vue 爷孙组件通讯之:Provide / Inject 详细介绍

背景

       在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,层层传递非常麻烦。

        对于这种情况,我们可以使用一对 provide 和 inject。无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。

        这个特性有两个部分:父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

vue2中的使用:

使用1: A->C 传递数据;

假设有一个组件A,A组件引入B组件(A为B的父组件) ,B组件引入C组件(B为C的父组件),即A为C的祖先组件,此时二者可以使用provide / inject进行通信。

-------------------------------- A 组件 ---------------------
<template><div><B></B></div>
</template><script>
import B from "./B.vue";
export default {name: "A",components: {B},provide:{name:"我是A提供的数据name",    // 这种情况下,非响应式,可以写成return的形式作为响应式},provide:{return {obj:this.obj,age:12,}}};
</script>
------------------------------ B 组件 ---------------------------
<template><div><C></C></div>
</template><script>
import C from "./C.vue";
export default {name: "B",components: {C},
};
</script>
-------------------------------C组件-------------------------------------
<template><div>{{name}}          // 非响应式写法{{obj.name}}      // 响应式{{age}}</div>
</template><script>
export default {name: "C",inject:["name","obj","age"]        // C组件在这里使用inject继承和接受a的数据
};
</script>

此时A中的name改变,C中的值也会相应跟着变化。

使用2: C->A  改变数据;

        以上为A向C传数据,如果C向A传数据(或者说C需要改变A中的数据),该如何做?

我们这里不让C直接改变A中的数据,而是将A改变数据的方法通过provide传给C,C执行该方法,触发改变A中的数据。

A使用provide传入一个方法

<template><div><span>{{obj.name}}</span><B></B></div>
</template><script>
import B from "./B.vue";
export default {name: "A",components: {B},provide(){return {changeVal:this.changeName      //传入一个方法}},data(){return {obj:{name:"leo"}}},methods:{changeName(val){          //C中触发该方法执行,此时变成"lion"this.obj.name = val}}
};
</script>

c使用inject 继承该方法,在自己的方法内调取改方法即可

<template><div><span @click="changeName">点击改变A组件数据</span></div>
</template><script>
export default {name: "C",inject:["changeVal"],    //接收一个方法methods:{changeName(){this.changeVal("lion")     //执行此方法,改变A中的数据}}
};
</script>

vue3 中的使用:

vue3:provide

在 setup() 中使用 provide 时,我们首先从 vue 显式导入 provide 方法。这使我们能够调用 provide 来定义每个 property。

provide 函数允许你通过两个参数定义 property:

  • name (<String> 类型)
  • value

使用A组件,provide 的值可以按如下方式重构:

<template><C />
</template><script>
import { provide } from 'vue'
import C from './C.vue'export default {components: {C},setup() {provide('location', 'North Pole')provide('geolocation', {longitude: 90,latitude: 135})}
}
</script>
vue3: inject

在 setup() 中使用 inject 时,也需要从 vue 显式导入。导入以后,我们就可以调用它来定义暴露给我们的组件方式。

inject 函数有两个参数:

要 inject 的 property 的 name
默认值 (可选)
使用C组件,可以使用以下代码对其进行重构:

<script>
import { inject } from 'vue'export default {setup() {const userLocation = inject('location', 'The Universe')const userGeolocation = inject('geolocation')return {userLocation,userGeolocation}}
}
</script>
provide响应式

为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 或 reactive。

<template><C />
</template><script>
import { provide, reactive, ref } from 'vue'
import C from './C.vue'export default {components: {C},setup() {const location = ref('North Pole')const geolocation = reactive({longitude: 90,latitude: 135})provide('location', location)provide('geolocation', geolocation)}
}
</script>

如果需要在c中修改a中的数据,需要向provide传入一个方法

<template><C />
</template><script>
import { provide, reactive, ref } from 'vue'
import C from './C.vue'export default {components: {C},setup() {const location = ref('North Pole')const geolocation = reactive({longitude: 90,latitude: 135})const updateLocation = () => {location.value = 'South Pole'}provide('location', location)provide('geolocation', geolocation)provide('updateLocation', updateLocation)     //传入一个方法}
}
</script>

c中调用该方法

<script>
import { inject } from 'vue'export default {setup() {const userLocation = inject('location', 'The Universe')const userGeolocation = inject('geolocation')const updateUserLocation = inject('updateLocation')return {userLocation,userGeolocation,updateUserLocation      //执行该方法,触发祖先组件方法执行,从而改变数据}}
}
</script>

最后,如果要确保通过 provide 传递的数据不会被 inject 的组件更改,我们建议对提供者的 property 使用 readonly

<template><C />
</template><script>
import { provide, reactive, readonly, ref } from 'vue'
import C from './C.vue'export default {components: {C},setup() {const location = ref('North Pole')const geolocation = reactive({longitude: 90,latitude: 135})const updateLocation = () => {location.value = 'South Pole'}// 使用readonly,数据只读provide('location', readonly(location))provide('geolocation', readonly(geolocation))provide('updateLocation', updateLocation)}
}
</script>


                        
参考文章:https://blog.csdn.net/qq_41809113/article/details/122071958

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/23569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在不受支持的 Mac 上安装 macOS Sonoma (OpenCore Legacy Patcher v1.5.0)

在不受支持的 Mac 上安装 macOS Sonoma (OpenCore Legacy Patcher v1.5.0) Install macOS on unsupported Macs 请访问原文链接&#xff1a;https://sysin.org/blog/install-macos-on-unsupported-mac/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主…

【leetcode--30.串联所有单词的子串】

有没有一样喜欢看示例的&#xff0c;&#xff0c;看题目就觉得很难懂。大致就是words要进行排列组合&#xff0c;返回s中所有包含这个排列组合的首标。 顺完逻辑蛮好懂的&#xff0c;应该不算困难题&#xff0c;只是不知道用什么模块实现。 class Solution:def findSubstring…

如何利用Varjo混合现实技术改变飞机维修训练方式

自2017年以来&#xff0c;总部位于休斯顿的HTX实验室一直在推进混合现实技术&#xff0c;与美国空军密切合作&#xff0c;通过其EMPACT平台提供可扩展的沉浸式飞机维护虚拟现实培训。 虚拟和混合现实对维修训练的好处&#xff1a; l 实践技能&#xff1a;提供一个非常接近真实场…

【C++题解】1074 - 小青蛙回来了

问题&#xff1a;1074 - 小青蛙回来了 类型&#xff1a;需要找规律的循环 题目描述&#xff1a; 关于小青蛙爬井的故事&#xff0c;你应该早就听过了&#xff1a;井深10 尺&#xff0c;小青蛙从井底向上爬&#xff0c;每个白天向上爬 3 尺&#xff0c;每个晚上又滑下来 2 尺&…

Java | Leetcode Java题解之第136题只出现一次的数字

题目&#xff1a; 题解&#xff1a; class Solution {public int singleNumber(int[] nums) {int single 0;for (int num : nums) {single ^ num;}return single;} }

App UI 风格,尽显魅力

精妙无比的App UI 风格

Eclipse添加C和C++编译成汇编文件的选项

在miscellaneous中添加assemble listing选项就可以生成汇编文件了

[自学记录09*]Unity Shader:在Unity里渲染一个黑洞

一、前言 记得很久很久以前&#xff0c;在ShaderToy上看过一个黑洞的效果&#xff0c;当时感觉太*8帅了&#xff0c;于是这几天就尝试自己弄了一个。 Gargantua With HDR Bloom (shadertoy.com) 下面是我自己实现的黑洞 可以看到还是略逊一筹&#xff08;感觉略逊百筹&#x…

07-指针的概念与引用,索引

指针的概念与引用&#xff0c;索引 一、内存地址 字节&#xff1a; 定义&#xff1a; 字节&#xff08;byte&#xff09;是内存容量的一个单位&#xff0c;一个字节包含8个位&#xff08;bit&#xff09;。 地址&#xff1a; 定义&#xff1a; 内存地址是系统为了方便区分…

DockerCompose中部署Jenkins(Docker Desktop在windows上数据卷映射)

场景 DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑&#xff1a; DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑_jenkins的安装以及集成jdkgitmaven 提示警告-CSDN博客 Windows10(家庭版…

c#vb代码互转工具

下载地址&#xff1a; https://download.csdn.net/download/wgxds/88979921

stm32中如何实现EXTI线 0 ~ 15与对应IO口的配置呢?

STM32的EXTI控制器支持19 个外部中断/ 事件请求。每个中断设有状态位&#xff0c;每个中断/ 事件都有独立的触发和屏蔽设置。 STM32的19个外部中断对应着19路中断线&#xff0c;分别是EXTI_Line0-EXTI_Line18&#xff1a; 线0~15&#xff1a;对应外部 IO口的输入中断。 线16&…

【MMU】——ARM 一级页表

文章目录 一级页表项即 entry 的格式如下 从上图可以看出 L1 页表项有四种可能类型 产生中止异常的故障条目。这可能是预取或数据中止、取决于访问类型。这实际上表示虚拟地址未映射 bit[1:0] = 00指向 L2 转换表的条目。这样就能将 1MB 的内存分页 bit[1:0] = 01。1MB 段转换…

STM32远程更新

1 IAP 概述 1.1 工作原理 在应用中编程&#xff08; IAP &#xff09;是一种在现场通过 MCU 的通信接口&#xff08;例如 UART,USB,CAN 和以太网 等&#xff09;进行固件升级的方式。 当启动微控制器时&#xff0c;您可以选择让它进入 IAP 模式以执行 IAP 代码&am…

04-240606Spark笔记

04-240606Spark笔记 1.行动算子-2 save相关算子: 格式: def saveAsTextFile(path: String): Unit def saveAsObjectFile(path: String): Unit def saveAsSequenceFile(path: String,codec: Option[Class[_ <: CompressionCodec]] None): Unit 例子: val rdd sc.makeR…

【Python报错】已解决NameError: name ‘Image‘ is not defined

解决Python报错&#xff1a;NameError: name ‘Image’ is not defined 在使用Python进行图像处理时&#xff0c;我们经常使用Pillow库&#xff08;PIL的一个分支&#xff09;。如果你在尝试创建或处理图像时遇到了NameError: name Image is not defined的错误&#xff0c;这通…

关于python包导入问题的重思考

将顶层目录直接设置为一个包 像这样&#xff0c;每一个文件从顶层包开始导入 这样可以解决我的问题&#xff0c;但是要注意的时&#xff0c;要避免使用出现上下级出现同名包的情况&#xff0c;比如&#xff1a; AutoServer--AutoServer--__init__.py--__init__.py这种情况下…

绿联云NAS一些探索(1):SSH、包管理器探测、安装docker-compose等

绿联云NAS一些探索SSH、包管理器探测、安装docker-compose等 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https:…

AI图书推荐:《如何利用ChatGPT在线赚钱》

这本书《如何利用ChatGPT在线赚钱》&#xff08;$100m ChatGPT_ How To Make Money Online With ChatGPT -- Sharp, Biily -- 2023 &#xff09;主要阐述如何利用ChatGPT这一强大的语言模型工具在互联网上创造收入。 以下是各章节内容的概要&#xff1a; **引言** - 介绍了Chat…

STM32F103单片机工程移植到航顺单片机HK32F103注意事项

一、简介 作为国内MCU厂商中前三阵营之一的航顺芯片&#xff0c;建立了世界首创超低功耗7nA物联网、万物互联核心处理器浩瀚天际10X系列平台&#xff0c;接受代理商/设计企业/方案商定制低于自主研发十倍以上成本&#xff0c;接近零风险自主品牌产品&#xff0c;芯片设计完成只…