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.pswp.cn/web/23569.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23569.shtml
英文地址,請注明出處:http://en.pswp.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…

什么是容器技術

容器虛擬化技術是一種有效的將單個操作系統的資源劃分到獨立的組中的技術&#xff0c;以便更好地在獨立的組之間平衡有沖突的資源使用需求。這種技術通過“偽造”操作系統的接口&#xff0c;將函數庫層以上的功能置于操作系統上&#xff0c;從而實現應用程序級別的虛擬化。容…

07-指針的概念與引用,索引

指針的概念與引用&#xff0c;索引 一、內存地址 字節&#xff1a; 定義&#xff1a; 字節&#xff08;byte&#xff09;是內存容量的一個單位&#xff0c;一個字節包含8個位&#xff08;bit&#xff09;。 地址&#xff1a; 定義&#xff1a; 內存地址是系統為了方便區分…

Java 主鍵生成策略之雪花算法

概述 項目中為了緩解數據庫服務器壓力和提高并發量進行分庫分表,在新增數據時,如果此時按照傳統方式使用數據庫主鍵自增,那么在并發下ID可能會沖突; 使用UUID的話又因其無序會產生頁分裂導致磁盤IO過大使得系統性能降低; 經過了解雪花算法根據其特點可以解決分布式系統中生成…

DockerCompose中部署Jenkins(Docker Desktop在windows上數據卷映射)

場景 DockerJenkinsGiteeMaven項目配置jdk、maven、gitee等拉取代碼并自動構建以及遇到的那些坑&#xff1a; DockerJenkinsGiteeMaven項目配置jdk、maven、gitee等拉取代碼并自動構建以及遇到的那些坑_jenkins的安裝以及集成jdkgitmaven 提示警告-CSDN博客 Windows10(家庭版…

AI學習指南機器學習篇-邏輯回歸正則化技術

AI學習指南機器學習篇-邏輯回歸正則化技術 在機器學習領域&#xff0c;邏輯回歸是一種常見的分類算法&#xff0c;它常用于處理二分類問題。在實際的應用中&#xff0c;為了提高模型的泛化能力和降低過擬合風險&#xff0c;邏輯回歸算法通常會使用正則化技術。本文將介紹邏輯回…

待定待定待定

BindingNavigator C# 屬性&#xff08;Property&#xff09; get set StringBuilder https://www.bilibili.com/video/BV15u4y1F72C/ C# 高級數據結構有哪些 List - 動態數組&#xff0c;可以動態增長和縮減&#xff0c;提供快速訪問、添加和刪除元素的功能。Dictionary<TK…

c#vb代碼互轉工具

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

EN 17104-2021室內用熱塑性硬質保護墻板CE認證

室內用熱塑性硬質保護墻板是指由同材質或非均質塑料板制成的&#xff0c;表面有或者沒有裝飾層&#xff0c;用于墻體的保護作用而非起結構作用&#xff0c;通過膠粘劑粘貼安裝。 EN 17104-2021室內用熱塑性硬質保護墻板CE認證項目 認證項目 測試標準 防火 EN 13501-1 揮發…

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…

Linux-用戶管理與軟件管理

用戶授權 如果普通用戶需要執行特殊操作&#xff0c;有兩種方法 1、su - root 切換到root賬號進行特殊操作&#xff0c;然后再返回到普通用戶 2、sudo命令 命令&#xff1a;su 優點&#xff1a;使用簡單 缺點&#xff1a;1、root密碼容易泄露&#xff1b;2、普通用…