請談談 Vue 中的響應式原理,如何實現?

一、Vue2響應式原理:Object.defineProperty的利與弊

實現原理

// 數據劫持核心實現
function defineReactive(obj, key, val) {const dep = new Dep(); // 依賴收集容器Object.defineProperty(obj, key, {get() {if (Dep.target) { // 當前Watcher實例dep.addSub(Dep.target); // 收集依賴}return val;},set(newVal) {if (val === newVal) return;val = newVal;dep.notify(); // 觸發更新}});
}// 遍歷對象屬性實現響應式
function observe(data) {Object.keys(data).forEach(key => {defineReactive(data, key, data[key]);});
}// 使用示例
const data = { count: 0 };
observe(data);

典型問題

  1. 無法檢測新增屬性
data.newProp = 'test'; // 不會觸發更新
// 必須使用 Vue.set(data, 'newProp', 'test')
  1. 數組操作需要特殊處理
// 直接修改數組下標無效
data.arr[0] = 1; // 不觸發更新
// 必須使用變異方法:push/pop/splice等
data.arr.splice(0, 1, 1);

二、Vue3響應式原理:Proxy的降維打擊

實現原理

function reactive(obj) {return new Proxy(obj, {get(target, key, receiver) {track(target, key); // 依賴收集return Reflect.get(target, key, receiver);},set(target, key, value, receiver) {Reflect.set(target, key, value, receiver);trigger(target, key); // 觸發更新return true;}});
}// 使用示例
const state = reactive({ count: 0 });
state.newProp = 'test'; // 直接生效!
state.arr[0] = 1; // 直接生效!

優勢對比

特性Vue2(defineProperty)Vue3(Proxy)
新增屬性監聽? 需要Vue.set? 原生支持
數組操作? 需特殊方法? 原生支持
嵌套對象性能? 遞歸劫持? 按需代理

三、日常開發建議與避坑指南

1. 數據操作規范
// Vue2正確姿勢
this.$set(this.obj, 'newKey', value);
this.arr.splice(index, 1, newValue);// Vue3正確姿勢(直接操作)
state.obj.newKey = value;
state.arr[index] = newValue;
2. 性能優化技巧
// 避免深層響應式(Vue3)
import { shallowRef } from 'vue';
const bigObject = shallowRef({ ... }); // 只跟蹤.value變化// 計算屬性緩存
const doubleCount = computed(() => count.value * 2);// 批量更新(Vue3)
import { nextTick } from 'vue';
async function batchUpdate() {state.a = 1;state.b = 2;await nextTick(); // DOM更新完成
}
3. 典型錯誤示例
// 錯誤1:解構丟失響應式(Vue3)
const { count } = reactiveObj; // ? 丟失響應式
const count = toRef(reactiveObj, 'count'); // ? 正確方式// 錯誤2:異步更新陷阱
setTimeout(() => {state.count++; // 可能觸發多次渲染
}, 100);// 正確做法(Vue3)
watchEffect(() => {// 自動追蹤依賴console.log(state.count);
});

四、響應式系統設計啟示

  1. 依賴收集流程

    • 組件渲染時觸發getter
    • 將當前Watcher存入Dep
    • 數據變更時通過Dep通知所有Watcher
  2. 更新隊列機制

    // 偽代碼實現
    let queue = [];
    function queueWatcher(watcher) {if (!queue.includes(watcher)) {queue.push(watcher);nextTick(flushQueue);}
    }
    function flushQueue() {queue.forEach(watcher => watcher.run());queue = [];
    }

五、面試高頻問題參考

  1. Vue2/3響應式實現差異的本質原因是什么?

    • 答:Object.defineProperty的局限性 vs Proxy的語言層支持
  2. 為什么Vue3放棄defineProperty?

    • 答:無法處理Map/Set等新數據結構、數組操作限制、性能開銷大
  3. 如何實現自定義響應式系統?

    • 參考思路:Proxy + 依賴收集 + 調度器設計

總結建議

  • 項目選型:新項目直接用Vue3,老項目逐步遷移
  • 開發習慣:避免深層嵌套數據結構,合理使用shallowRef
  • 調試技巧:利用Vue Devtools觀察依賴關系
  • 進階學習:閱讀@vue/reactivity源碼(僅1800行)

響應式系統是Vue的核心競爭力,理解其實現原理能幫助開發者寫出更高效可靠的代碼。建議結合項目實際,多實踐不同場景下的數據流管理。

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

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

相關文章

第6章:基于LangChain如何開發Agents,附帶客戶支持智能體示例

本文主要介紹了 LangChain4j 中的 Agent(代理) 概念,以及如何使用 LangChain4j 構建代理系統,重點提供了一個客戶支持系統的智能體樣例 代理(Agents)| LangChain4j 注意: 請注意,“A…

Android 中使用 FFmpeg 進行音視頻處理

1. FFmpeg 基礎知識 1.1 什么是 FFmpeg? FFmpeg 是一個開源的多媒體處理工具,支持音視頻的編碼、解碼、轉碼、裁剪、合并、濾鏡、流媒體等功能。它是一個命令行工具,支持多種音視頻格式和編解碼器。1.2 為什么在 Android 中使用 FFmpeg? Android 自帶的多媒體 API(如 Med…

Matplotlib 高級圖表繪制與交互式可視化(ipywidgets)

目錄: ipywidgets 介紹 1. 什么是 ipywidgets 直接開始: 動態調整正弦波頻率 隨機散點圖 啟用交互式模式 使用滑塊和下拉菜單調整圖表樣式 使用布局管理器創建復雜界面 使用動畫創建動態圖表 最后: 綜合示例:動態儀表盤 ipywidgets 介紹 1. 什么是 ipywidgets i…

【FAQ】HarmonyOS SDK 閉源開放能力 —Live View Kit (1)

1.問題描述: 客戶端創建實況窗后,通過Push kit更新實況窗內容,這個過程是自動更新的還是客戶端解析push消息數據后填充數據更新?客戶端除了接入Push kit和創建實況窗還需要做什么工作? 解決方案: 通過Pu…

uvm中的激勵是如何發送出去的

在UVM中,Sequence生成的激勵(Transaction)通過以下協作流程發送到Driver并最終驅動到DUT,其核心機制如下: --------------- --------------- ------------ ----- | Sequence | → | Seque…

SpringAI系列 - ToolCalling篇(二) - 如何設置應用側工具參數ToolContext(有坑)

目錄 一、引言二、集成ToolContext示例步驟1: 在`@Tool`標注的工具方法中集成`ToolConext`參數步驟2:`ChatClient`運行時動態設置`ToolContext`參數三、填坑一、引言 在使用AI大模型的工具調用機制時,工具參數都是由大模型解析用戶輸入上下文獲取的,由大模型提供參數給本地…

【RabbitMQ業務冪等設計】RabbitMQ消息是冪等的嗎?

在分布式系統中,RabbitMQ 自身不直接提供消息冪等性保障機制,但可通過業務邏輯設計和技術組合實現消息處理的冪等性。以下是 8 種核心實現方案及最佳實踐: 一、消息唯一標識符 (Message Deduplication) 原理 每條消息攜帶全局唯一ID&#xff…

網絡可靠性要求

目錄 一、背景介紹 二、環路引發的危害 1、廣播風暴 2、MAC 地址表震蕩 三、STP生成樹 1、STP的作用 2、STP工作過程 3、根橋選舉 4、根端口選舉 5、指定端口選舉 6、BPDU報文分析 7、計時器 8、端口狀態轉化 總結 一、背景介紹 為了提高網絡可靠性,交換網絡…

《STL 六大組件之容器探秘:深入剖析 string》

目錄 一、string 類簡介二、string 類的常用接口1. 構造函數(constructor function)2. 與容量相關的接口(capacity)3. 與迭代器有關的接口(iterator)4. 與元素訪問有關的接口(element access&am…

Unreal5從入門到精通之在編輯器中更新 UserWidgets

前言 在虛幻中創建越來越復雜和靈活的 UserWidget 藍圖時,一個問題是它們在編輯器中的外觀與它們在游戲中的最終外觀可能有很大不同。 庫存面板示例 假設你想創建一個通用的庫存顯示小部件。我們可以在整個 UI 中使用它,無論我們需要在哪里顯示某些內容。 標題,描述所顯示…

計算機網絡-OSI七層參考模型與數據封裝,網絡安全零基礎入門到精通實戰教程!

目錄 一、網絡 1、網絡的定義 2、網絡的分類 3、網絡的作用 4、網絡的數據傳輸方式 5、網絡的數據通訊方式 二、OSI七層參考模型 1、網絡參考模型定義 2、分層的意義 3、分層與功能 4、TCP\IP五層模型 三、參考模型的協議 1、物理層 2、數據鏈路層 3、網絡層 4…

Python正則替換終極指南:用re.sub玩轉字符串魔法

Python正則替換終極指南:用re.sub玩轉字符串魔法 一、為什么re.sub是文本處理的瑞士軍刀? 在Python的re模塊中,re.sub()的周下載量突破5800萬次(2025年PyPI數據),它實現了: 📍 模…

gen_gauss_filter用于檢測帶方向的線條

目錄 一、核心參數分析 1.1 方向覆蓋范圍 1.2 濾波器方向帶寬 二、角度配置建議 三、參數選擇依據 四、實施建議 五、模擬圖測試(項目圖檔不好直接分享) 5.1 模擬圖制作 5.2 檢測偽代碼 在Halcon中使用高斯濾波器檢測多方向線條時,角度參數的選取需要綜合考慮濾波…

C++17 中的 std::to_chars 和 std::from_chars:高效且安全的字符串轉換工具

文章目錄 1. 傳統轉換方法的局限性2. std::to_chars:數值到字符串的高效轉換函數原型:返回值:示例代碼:輸出: 3. std::from_chars:字符串到數值的高效解析函數原型:返回值:示例代碼&…

深入學習解析:183頁可編輯PPT華為市場營銷MPR+LTC流程規劃方案

華為終端正面臨銷售模式轉型的關鍵時刻,旨在通過構建MPRLTC項目,以規避對運營商定制的過度依賴,并探索新的增長路徑。項目核心在于建設一套全新的銷售流程與IT系統,支撐雙品牌及自有品牌的戰略發展。 項目總體方案聚焦于四大關鍵議…

Python正則表達式處理中日韓字符過濾全解析

Python正則表達式處理中日韓字符過濾全解析 一、核心原理:Unicode字符范圍定位 中日韓字符在Unicode中的分布: 中文:\u4e00-\u9fff(基本區) \u3400-\u4dbf(擴展A區) \U00020000-\U0002a6df…

基于WOA鯨魚優化的WSN網絡最優節點部署算法matlab仿真

目錄 1.程序功能描述 2.測試軟件版本以及運行結果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 鯨魚優化算法(WOA)是一種模擬座頭鯨捕食行為的元啟發式優化算法。其主要原理基于座頭鯨獨特的 “氣泡網” 捕食策略,通過數學模…

【數據分析】3 數據分析成長之路

職業發展路徑: 向上發展(技術方向):可以詳細說明成為數據科學家或專家所需的具體技能和步驟,包括學習的算法、工具等。向下發展(業務方向):可以探討結合業務知識的具體領域&#xff…

excel導入Mysql中時間格式異常

問題描述: 當使用xls/xlsx/csv導入mysql中,如果列是時間類型比如excel表中顯示2024/02/20 09:18:00,導入后時間可能就會變成1900-01-01 09:18:00這樣。 問題原因: 這是由于excel表中和數據庫中的時間類型不匹配導致。 問題解決…

async checkpointing

Reducing Model Checkpointing Times by Over 10x with PyTorch Distributed Asynchronous Checkpointing | PyTorch 最初來源:IBM Research 核心思想:GPU->CPU,用的是blocking;CPU->Disk,用的是異步不阻塞訓練…