provide/inject源碼實現

在 Vue 3 中,provide 和 inject 是通過 Vue 的響應式系統和組件實例機制實現的,底層是依賴 Vue 3 中的 Proxy 和 Reactive 來實現跨層級的數據傳遞和響應式綁定。以下是一個簡化版的實現邏輯,幫助理解 Vue 3 中 provide 和 inject 是如何實現的。

  1. provide 的實現

provide 的核心目的是將數據存儲在當前組件的上下文中,然后將這些數據傳遞給其后代組件。Vue 3 使用 Proxy 來實現對組件上下文的響應式管理。

基本的實現思路:

在父組件中,使用 provide 將數據存儲到一個上下文對象中,父組件上下文數據存儲在當前組件實例的 provides 對象中。

父組件的 provides 會暴露給子組件,子組件可以從父組件的上下文中讀取提供的數據。

簡化版的實現邏輯如下:

class Component {
constructor() {
this.provides = new Map(); // 存儲提供的數據
}

provide(key, value) {
this.provides.set(key, value); // 設置提供的數據
}

inject(key) {
return this.provides.get(key); // 從當前組件的 provides 中獲取
}
}

示例:

const parentComponent = new Component();
parentComponent.provide(‘user’, { name: ‘John’, age: 30 });

const childComponent = new Component();
const user = childComponent.inject(‘user’); // 獲取父組件提供的數據
console.log(user); // 輸出: { name: ‘John’, age: 30 }

  1. inject 的實現

inject 用來從當前組件的父組件(或祖先組件)中獲取提供的數據。在實際實現中,Vue 會查找組件的父鏈(即組件樹)來查找所需的 provide 數據。

基本的實現思路:

在子組件中,使用 inject 來獲取上層組件通過 provide 提供的數據。Vue 會遍歷組件樹,查找最近的祖先組件。

如果當前組件沒有提供數據,Vue 會繼續向上查找直到根組件。

class Component {
constructor(parent = null) {
this.parent = parent;
this.provides = new Map(); // 存儲提供的數據
}

provide(key, value) {
this.provides.set(key, value);
}

inject(key) {
// 從當前組件開始,逐級向父組件查找數據
let currentComponent = this;
while (currentComponent) {
if (currentComponent.provides.has(key)) {
return currentComponent.provides.get(key);
}
currentComponent = currentComponent.parent;
}
return undefined; // 如果找不到提供的數據,返回 undefined
}
}

示例:

// 父組件提供數據
const parentComponent = new Component();
parentComponent.provide(‘user’, { name: ‘John’, age: 30 });

// 子組件繼承父組件
const childComponent = new Component(parentComponent);

// 孫組件繼承子組件
const grandchildComponent = new Component(childComponent);

// 孫組件注入父組件提供的數據
const user = grandchildComponent.inject(‘user’);
console.log(user); // 輸出: { name: ‘John’, age: 30 }

  1. 響應式機制

在 Vue 3 中,provide 和 inject 采用的是基于 Proxy 的響應式系統。Vue 3 的響應式系統使用 Proxy 來監聽對象的變化,確保在數據變更時能夠觸發視圖更新。

為了實現響應式傳遞,Vue 會通過 reactive 來包裝提供的數據,然后使用 provide 提供的值會是一個響應式對象,子組件通過 inject 獲取該對象時,數據的變化會自動反應到視圖中。

簡化的響應式實現:

function reactive(obj) {
return new Proxy(obj, {
get(target, prop) {
console.log(Accessing ${prop}); // 打印屬性訪問的日志
return target[prop];
},
set(target, prop, value) {
console.log(Setting ${prop} to ${value}); // 打印屬性設置的日志
target[prop] = value;
return true;
}
});
}

class Component {
constructor(parent = null) {
this.parent = parent;
this.provides = new Map();
}

provide(key, value) {
this.provides.set(key, reactive(value)); // 提供響應式數據
}

inject(key) {
let currentComponent = this;
while (currentComponent) {
if (currentComponent.provides.has(key)) {
return currentComponent.provides.get(key); // 返回響應式數據
}
currentComponent = currentComponent.parent;
}
return undefined;
}
}

示例:

// 父組件提供響應式數據
const parentComponent = new Component();
const user = { name: ‘John’, age: 30 };
parentComponent.provide(‘user’, user);

// 子組件繼承父組件
const childComponent = new Component(parentComponent);

// 孫組件繼承子組件
const grandchildComponent = new Component(childComponent);

// 孫組件注入父組件提供的響應式數據
const injectedUser = grandchildComponent.inject(‘user’);
injectedUser.name = ‘Jane’; // 通過代理修改數據

console.log(user.name); // 輸出: Jane,數據變化自動反映

總結

Vue 3 中的 provide 和 inject 實現是基于 Proxy 的響應式系統,組件的 provides 數據是響應式的,當數據變化時,依賴這些數據的組件會自動更新。provide 用來提供數據,inject 用來注入數據,支持跨組件層級的數據共享。通過 Proxy,Vue 3 能夠實現跨層級數據傳遞和數據的自動更新,使得組件間的數據通信更加靈活和高效。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73647.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73647.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73647.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unix時間戳BKP備份寄存器RTC實時時鐘

Unix時間戳 Unix時間戳,也稱為POSIX時間或Epoch時間,是一種在Unix和類Unix操作系統中使用的時間表示方法。它表示的是自1970年1月1日00:00:00 UTC(協調世界時)至當前時間經過的秒數,不考慮閏秒。Unix時間戳通常以秒為…

【Linux內核系列】:進程板塊與文件板塊的綜合

🔥 本文專欄:Linux 🌸作者主頁:努力努力再努力wz 💪 今日博客勵志語錄: 人生中成功只是一時的,失敗卻是人生的主旋律,但是如何面對失敗卻把人分成了不同的樣子,有的人會被…

CellOracle|基因擾動研究基因功能|基因調控網絡+虛擬干預

在gzh“生信小鵬”同步文章 論文來源: 發表期刊:Nature發表時間:2023年2月23日論文題目:Dissecting cell identity via network inference and in silico gene perturbation研究團隊:Kenji Kamimoto 等,華盛頓大學醫學院1. 研究背景與問題提出 細胞身份(Cell Identit…

專線、云 和 物聯網(IoT)

專線、云 和 物聯網(IoT) 是現代信息與通信技術(ICT)領域的三大重要組成部分,它們在企業和個人的數字化轉型中扮演著關鍵角色。以下是對這三者的詳細介紹及其相互關系: 1. 專線(Leased Line&…

[Lc14_priority_queue] 最后一塊石頭重量 | 數據流中的第 K 大元素 | 前K個高頻單詞 | 數據流的中位數

目錄 1.最后一塊石頭的重量 題解 2.數據流中的第 K 大元素 題解 3.前K個高頻單詞 題解 代碼 ?4.數據流的中位數 題解 在C中,使用標準庫中的priority_queue,默認情況下它是一個最大堆(即大堆排序),這意味著最…

XSS漏洞靶場---(復現)

XSS漏洞靶場—(復現) 反射型 XSS 的特點是攻擊者誘導用戶點擊包含惡意腳本的 URL,服務器接收到請求后將惡意腳本反射回響應頁面,瀏覽器執行該腳本從而造成攻擊,惡意腳本不會在服務器端存儲。 Level 1(反射型XSS) 此漏…

2025/3.17 郭院安排會議與南京銀行參訪

目錄 *郭院會議:服務外包*1.會遇到的問題以及解決方案2.考慮行業目前會碰到的瓶頸3.后端應該呈現處理圖像的過程4.記得做報告、文檔說明和視頻等工作 *南京銀行(鑫合易家)參訪記錄*1. 風險評分業務流程筆記![在這里插入圖片描述](https://i-b…

Cloud Ace 宣布成為 Langfuse 亞太地區首個代理商,提供 LLM 全鏈路解決方案

Cloud Ace 宣布正式代理 Langfuse 產品,是 Langfuse 在亞太地區唯一的官方授權經銷商,全面負責其商用許可證的銷售、部署與技術支持服務。通過此次合作,Cloud Ace 將充分發揮 Langfuse 的先進技術能力與行業專業知識,為企業級客戶…

Helm 的倉庫管理與 Chart 搜索

在使用 Helm 管理 Kubernetes 應用的過程中,倉庫管理與 Chart 搜索是兩個核心功能。通過 Helm 倉庫,用戶可以方便地存儲、分享和獲取 Helm Chart,而搜索功能則幫助用戶快速找到所需的 Chart。本文將詳細介紹 Helm 倉庫的概念、管理方法以及如…

Matlab 汽車振動多自由度非線性懸掛系統和參數研究

1、內容簡介 略 Matlab 169-汽車振動多自由度非線性懸掛系統和參數研究 可以交流、咨詢、答疑 2、內容說明 略 第二章 汽車模型建立 2.1 汽車懸架系統概述 2.1.1 懸架系統的結構和功能 2.1.2 懸架分類 2.2 四分之一車輛模型 對于車輛動力學,一般都是研究其懸…

免訓練指標(Zero-Cost Proxies)

1. 什么是免訓練指標(Zero-Cost Proxies,ZC proxies)? 免訓練指標是一類 無需完整訓練模型即可評估其性能的度量方法,主要用于提高 神經架構搜索(NAS) 的效率。 傳統 NAS 需要訓練候選架構來評…

C語言 —— 此去經年夢浪蕩魂音 - 深入理解指針(卷二)

目錄 1. 數組名與地址 2. 指針訪問數組 3.一維數組傳參本質 4.二級指針 5. 指針數組 6. 指針數組模擬二維數組 1. 數組名與地址 我們先看下面這個代碼: int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int* p &arr[0]; 這里我們使用 &arr[0] 的方式拿到了數…

基于Python pyscard庫采集ACS ACR122U NFC讀卡器數據的詳細操作步驟

步驟1:安裝驅動 1. 下載驅動: - 訪問ACS官網的驅動下載頁面:[ACR122U驅動下載](https://www.acs.com.hk/en/drivers/6/acr122u-nfc-reader/)。 - 選擇適用于Windows的驅動(如 ACR122U Driver (Windows) V3.05.02.zip)…

深度學習 Deep Learning 第1章 深度學習簡介

第1章 深度學習簡介 概述 本章介紹人工智能(AI)和深度學習領域,討論其歷史發展、關鍵概念和應用。解釋深度學習如何從早期的AI和機器學習方法演變而來,以及如何有效解決之前方法無法應對的挑戰。 關鍵概念 1. 人工智能的演變 …

python實現簡單的圖片去水印工具

python實現簡單的圖片去水印工具 使用說明: 點擊"打開圖片"選擇需要處理的圖片 在圖片上拖拽鼠標選擇水印區域(紅色矩形框) 點擊"去除水印"執行處理 點擊"保存結果"保存處理后的圖片 運行效果 先簡要說明…

軟件功能性測試有哪些步驟和挑戰?軟件測評服務機構分享

軟件功能性測試是對軟件系統進行驗證的一種基本方法。其主要目標是確保軟件系統能夠按照預期的要求和功能進行操作。從用戶的角度看,功能性測試旨在檢查軟件是否實現了所有要求的功能,保證用戶體驗的順暢與滿意。 一、軟件功能性測試的測試步驟   1、…

《C#上位機開發從門外到門內》3-4:基于TCP/IP的遠程監控系統設計與實現

文章目錄 一、項目概述二、系統架構設計三、通信協議設計四、功能模塊實現五、系統安全性與穩定性六、性能優化與測試七、實際應用案例八、結論 隨著信息技術的飛速發展,遠程監控系統在工業自動化、智能家居、環境監測等領域的應用日益廣泛。基于TCP/IP協議的遠程監…

在react當中利用IntersectionObserve實現下拉加載數據

目錄 一、傳統的下拉加載方案 二、存在問題 1.性能較差 2.不夠精確 三、IntersectionObserve版本下拉加載 1、callback 2、options 四、IntersectionObserver實例 1、Intersection的優勢 2、實現思路 3、代碼實現 在進行前端開發的過程中,常常會碰到下拉…

深入理解C++編程:從內存管理到多態與算法實現

C 是一門功能強大的編程語言,廣泛應用于系統編程、游戲開發和高性能計算等領域。本文將通過一系列經典問題,深入探討 C 的核心知識點,包括內存管理、多態(結合函數重載與覆蓋)、多線程、TCP/IP 模型、軟鏈接與硬鏈接的…

相對論之光速

然而,基礎物理學的進步很少全部由實驗取得。為了解實驗結果背后的機制,法拉第問道,既然磁鐵沒有接觸導線,導線中怎么會產生電流?一股電流又怎么能使指南針指針發生偏轉?有某種作用因素必然在磁鐵、導線和指南針之間的空隙中傳遞…