Vue3響應式原理那些事

文章目錄

    • 1 響應式基礎:Proxy 與 Reflect
      • 1.1 Proxy 代理攔截
      • 1.2 Reflect 確保 `this` 指向正確
        • 1.2.1 修正 `this` 指向問題
        • 1.2.2 統一的操作返回值
      • 1.3 與 Vue2 的對比
    • 2 依賴收集與觸發機制
      • 2.1 全局依賴存儲結構:WeakMap → Map → Set
      • 2.2 依賴收集觸發時機
      • 2.3 依賴收集核心實現:track 函數
      • 2.4 依賴觸發:trigger 函數
      • 2.5 副作用管理:ReactiveEffect 類
      • 2.6 特殊場景處理:ref 的依賴收集
      • 2.7 設計亮點
    • 3 響應式 API 的封裝
      • 3.1. `reactive`
      • 3.2 `ref`
      • 3.3 `reactive` 與 `ref` 核心區別
      • 3.4 注意事項
    • 4 雙向綁定實現(v-model)
      • 4.1 原生 DOM 元素的實現原理
        • 4.1.1 屬性綁定
        • 4.1.2 響應式更新
      • 4.2 自定義組件的實現原理
        • 4.2.1 傳統模式(Vue3.4 前)
        • 4.2.2 `defineModel` 宏(Vue3.4+)
      • 4.3 響應式系統的支撐
      • 4.4 性能優化與擴展性
    • 5 對比 Vue2 的改進

近期文章

  • Vue3開發常見性能問題知多少
  • Vue3組件常見通信方式你了解多少?
  • 實現篇:LRU算法的幾種實現
  • 從底層視角看requestAnimationFrame的性能增強
  • Nginx Upstream了解一下
  • 實現篇:一文搞懂Promise是如何實現的
  • 實現篇:如何手動實現JSON.parse
  • 實現篇:如何親手定制實現JSON.stringify
  • 一文搞懂 Markdown 文檔規則

Vue3 的雙向響應式原理是其核心機制,通過 Proxy 代理與 依賴收集系統 實現數據與視圖的自動同步。以下是其核心原理與技術細節的深度解析:

1 響應式基礎:Proxy 與 Reflect

Vue3 徹底拋棄了 Vue2 的 Object.defineProperty,改用 ES6 Proxy 實現數據劫持,解決了 Vue2 無法監聽對象屬性新增/刪除、數組索引修改等問題。

1.1 Proxy 代理攔截

Proxy 可攔截對象的所有操作(如 getsetdeleteProperty 等),解決了 Vue2 中 Object.defineProperty 無法監聽新增屬性數組索引修改的問題。

Proxy 默認采用惰性代理,僅在訪問嵌套對象時遞歸創建代理,優化了性能。

const handler = {get(target, key, receiver) {track(target, key); // 依賴收集return Reflect.get(target, key, receiver);},set(target, key, value, receiver) {const result = Reflect.set(target, key, value, receiver);trigger(target, key); // 觸發更新return result;}
};
const proxyData = new Proxy(data, handler);

1.2 Reflect 確保 this 指向正確

Reflect 的靜態方法與 Proxy 的攔截器一一對應,確保操作的一致性和安全性:

1.2.1 修正 this 指向問題

當代理對象包含訪問器屬性(如 get c() { return this.a + this.b })時,若直接通過 target[key] 讀取屬性,this 會指向原對象而非代理對象,導致后續屬性訪問無法觸發 Proxy 攔截。

解決方案:使用 Reflect.get(target, key, receiver),其中 receiver 顯式傳遞代理對象,確保 this 指向正確。

 // 錯誤示例(this指向原對象)get(target, key) { return target[key]; }// 正確示例(通過Reflect修正this)get(target, key, receiver) { return Reflect.get(target, key, receiver); }
1.2.2 統一的操作返回值

Reflect 方法返回布爾值(如 Reflect.set() 返回操作是否成功),簡化了錯誤處理流程。

1.3 與 Vue2 的對比

特性Vue2 (Object.defineProperty)Vue3 (Proxy + Reflect)
屬性監聽需遍歷屬性逐個劫持代理整個對象,自動處理新增/刪除屬性
數組支持需重寫數組方法直接攔截原生數組操作
性能初始化遞歸遍歷,性能較差惰性代理,按需觸發攔截
代碼復雜度需手動處理嵌套對象和數組原生支持復雜數據結構

2 依賴收集與觸發機制

Vue3 的依賴收集機制通過 Proxy 攔截訪問全局拓撲存儲精準觸發更新 的鏈路,實現了高效、精準的響應式更新。其 WeakMap 結構ReactiveEffect 雙向鏈接惰性代理 等特性,使得框架具備更高的性能。

2.1 全局依賴存儲結構:WeakMap → Map → Set

Vue3 使用三級數據結構管理依賴關系,確保高效的內存管理和精準的依賴追蹤:

// 源碼位置:packages/reactivity/src/effect.ts
type Dep = Set<ReactiveEffect>;
type KeyToDepMap = Map<any, Dep>;
const targetMap = new WeakMap<any, KeyToDepMap>(); // 全局依賴存儲// 結構示意:
WeakMap {[targetObject]: Map {[key]: Set<effect1, effect2...>}
}
  • WeakMap:鍵為原始對象(避免內存泄漏),值為 KeyToDepMap
  • KeyToDepMap:鍵為對象屬性名,值為 Dep(存儲關聯的副作用函數集合)。
  • DepSet<ReactiveEffect>,保證副作用的唯一性。

2.2 依賴收集觸發時機

當訪問響應式對象的屬性時,Proxy 的 get 攔截器觸發依賴收集流程:

// 源碼簡化:packages/reactivity/src/baseHandlers.ts
function createGetter() {return function get(target: object, key: string | 

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

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

相關文章

精選10個好用的WordPress免費主題

10個好用的WordPress免費主題 1. Astra Astra 是全球最受歡迎的WordPress免費主題。它功能豐富&#xff0c;易于使用&#xff0c;SEO友好&#xff0c;是第一個安裝量突破100萬的非默認主題&#xff0c;并獲得了5000多個五星好評。 它完美集成了Elementor、Beaver&#xff0c;…

【SaaS多租架構】數據隔離與性能平衡

SaaS多租戶架構:數據隔離與性能平衡 一、技術背景及發展二、技術特點:數據隔離與性能優化的雙核心三、技術細節:實現路徑與關鍵技術四、實際案例分析五、未來發展趨勢結語一、技術背景及發展 多租戶架構是云計算與SaaS(軟件即服務)模式的核心技術,其核心目標是通過共享基…

部署GM DC Monitor 一體化監控預警平臺

1&#xff09;首先在官網下載鏡像文件 廣目&#xff08;北京&#xff09;軟件有限公司廣目&#xff08;北京&#xff09;軟件有限公司https://www.gm-monitor.com/col.jsp?id1142&#xff09;其次進行部署安裝&#xff0c;教程如下&#xff1a; 1. 基礎環境要求 1) 系統&…

Webug4.0靶場通關筆記15- 第19關文件上傳(畸形文件)

目錄 第19關 文件上傳(畸形文件) 1.打開靶場 2.源碼分析 &#xff08;1&#xff09;客戶端源碼 &#xff08;2&#xff09;服務器源碼 3.滲透實戰 &#xff08;1&#xff09;構造腳本 &#xff08;2&#xff09;雙寫繞過 &#xff08;3&#xff09;訪問腳本 本文通過《…

架構思維:構建高并發讀服務_熱點數據查詢的架構設計與性能調優

文章目錄 一、引言二、熱點查詢定義與場景三、主從復制——垂直擴容四、應用內前置緩存4.1 容量上限與淘汰策略4.2 延遲刷新&#xff1a;定期 vs. 實時4.3 逃逸流量控制4.4 熱點發現&#xff1a;被動 vs. 主動 五、降級與限流兜底六、前端&#xff0f;接入層其他應對七、模擬壓…

寶塔面板運行docker的jenkins

1.在寶塔面板裝docker&#xff0c;以及jenkins 2.ip:端口訪問jenkins 3.獲取密鑰&#xff08;點擊日志&#xff09; 4.配置容器內的jdk和maven環境&#xff08;直接把jdk和maven文件夾放到jenkins容器映射的data文件下&#xff09; 點擊容器-->管理-->數據存儲卷--.把相…

C語言 ——— 函數

目錄 函數是什么 庫函數 學習使用 strcpy 庫函數 自定義函數 寫一個函數能找出兩個整數中的最大值 寫一個函數交換兩個整型變量的內容 牛刀小試 寫一個函數判斷一個整數是否是素數 寫一個函數判斷某一年是否是閏年 寫一個函數&#xff0c;實現一個整型有序數組的二分…

筆記本電腦升級計劃(2017———2025)

ThinkPad T470 (2017) vs ThinkBook 16 (2025) 完整性能對比報告 一、核心硬件性能對比 1. CPU性能對比&#xff08;i5-7200U vs Ultra9-285H&#xff09; 參數i5-7200U (2017)Ultra9-285H (2025)提升百分比核心架構2核4線程 (Skylake)16核16線程 (6P8E2LPE)700%核心數制程工…

具身系列——PPO算法實現CartPole游戲(強化學習)

完整代碼參考&#xff1a; https://gitee.com/chencib/ailib/blob/master/rl/ppo_cartpole.py 執行結果&#xff1a; 部分訓練得分&#xff1a; (sd) D:\Dev\traditional_nn\feiai\test\rl>python ppo_cartpole_v2_succeed.py Ep: 0 | Reward: 23.0 | Running: 2…

Python項目源碼60:電影院選票系統1.0(tkinter)

1.功能特點&#xff1a;通常選票系統應該允許用戶選擇電影、場次、座位&#xff0c;然后顯示總價和生成票據。好的&#xff0c;我得先規劃一下界面布局。 首先&#xff0c;應該有一個電影選擇的列表&#xff0c;可能用下拉菜單Combobox來實現。然后場次時間&#xff0c;可能用…

【全隊項目】智能學術海報生成系統PosterGenius--圖片布局生成模型LayoutPrompt(2)

&#x1f308; 個人主頁&#xff1a;十二月的貓-CSDN博客 &#x1f525; 系列專欄&#xff1a; &#x1f3c0;大模型實戰訓練營_十二月的貓的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻擋不了春天的腳步&#xff0c;十二點的黑夜遮蔽不住黎明的曙光 目錄 1. 前…

Linux的時間同步服務器(附加詳細實驗案例)

一、計時方式的發展 1.古代計時方式? 公元前約 2000 年&#xff1a;古埃及人利用光線留下的影子計時&#xff0c;他們修建高聳的大型方尖碑&#xff0c;通過追蹤方尖碑影子的移動判斷時間&#xff0c;這是早期利用自然現象計時的典型方式 。?商朝時期&#xff1a;人們開發并…

【無需docker】mac本地部署dify

環境安裝準備 #安裝 postgresql13 brew install postgresql13 #使用zsh的在全局添加postgresql命令集 echo export PATH"/usr/local/opt/postgresql13/bin:$PATH" >> ~/.zshrc # 使得zsh的配置修改生效 source ~/.zshrc # 啟動postgresql brew services star…

(5)概述 QT 的元對象系統里的類的調用與聯系,及訪問接口

&#xff08;1&#xff09; QT 的元對象系統&#xff0c;這幾個字大家都知道&#xff0c;那么 QT 的元對象系統里都包含哪些內容呢&#xff0c;其訪問接口是如何呢&#xff1f; 從 QObject 類的實現里&#xff0c;從其數據成員里就可以看出來&#xff1a; QT 里父容器可以釋放其…

打包 Python 項目為 Windows 可執行文件:高效部署指南

Hypackpy 是一款由白月黑羽開發的 Python 項目打包工具&#xff0c;它與 PyInstaller 等傳統工具不同&#xff0c;通過直接打包解釋器環境和項目代碼&#xff0c;并允許開發者修改配置文件以排除不需要的內容&#xff0c;從而創建方便用戶一鍵運行的可執行程序。以下是使用 Hyp…

MySQL JOIN詳解:掌握數據關聯的核心技能

一、為什么需要JOIN&#xff1f; 在關系型數據庫中&#xff0c;數據通常被拆分到不同的表中以提高存儲效率。當我們需要從多個表中組合數據時&#xff0c;JOIN操作就成為了最關鍵的技能。通過本文&#xff0c;您將全面掌握MySQL中7種JOIN操作&#xff0c;并學會如何在實際場景中…

Kdump 收集器及使用方式

以下是 Linux 系統中 Kdump 轉儲收集器的詳細說明及其使用方法&#xff0c;涵蓋核心工具、配置方法及實際示例&#xff1a; 一、Kdump 收集器分類及作用 Kdump 的核心功能是通過 捕獲內核 生成內存轉儲文件&#xff08;vmcore&#xff09;&#xff0c;其核心收集器包括&#…

Error: error:0308010C:digital envelope routines::unsupported 高版本node啟動低版本項目運行報錯

我的問題就是高版本node啟動舊版本項目引起的問題&#xff0c;單獨在配置 package.json文件中配置并運行就可以&#xff0c;大概意思就是設置node的openssl "scripts": {"dev": "SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-servi…

松下機器人快速入門指南(2025年更新版)

松下機器人快速入門指南&#xff08;2025年更新版&#xff09; 松下機器人以其高精度、穩定性和易用性在工業自動化領域廣泛應用。本文將從硬件配置、參數設置、手動操作、編程基礎到維護保養&#xff0c;全面講解松下機器人的快速入門方法&#xff0c;幫助新手快速掌握核心操…

【CISCO】Se2/0, Se3/0:串行口(Serial) 這里串口的2/0 和 3/0分別都是什么?

在 Cisco IOS 設備上&#xff0c;接口名稱通常遵循這樣一個格式&#xff1a; <類型><槽號>/<端口號>類型&#xff08;Type&#xff09;&#xff1a;表示接口的物理或邏輯類型&#xff0c;比如 Serial&#xff08;串行&#xff09;、FastEthernet、GigabitEt…