Vue2和Vue3響應(yīng)式原理對比分析
1. 底層實(shí)現(xiàn)方式
Vue 2 —Object.defineProperty
Vue 2 在初始化數(shù)據(jù)時,會遍歷對象的每個屬性,通過 Object.defineProperty 定義 getter 和 setter。
當(dāng)屬性被讀取時進(jìn)行依賴收集,被修改時觸發(fā)更新。
優(yōu)點(diǎn):
- ES5 時代最可行的響應(yīng)式方案
- API 簡單直觀
缺點(diǎn):
- 不能監(jiān)聽對象的新增/刪除屬性
- 無法監(jiān)聽數(shù)組索引和
length的變化
初始化時必須遞歸遍歷對象,性能消耗較大
Vue 3 —Proxy
Vue 3 使用了 ES2015 的 Proxy 來代理整個對象,對所有操作(讀取、修改、刪除、遍歷等)進(jìn)行攔截。
優(yōu)點(diǎn):
- 支持監(jiān)聽對象屬性的新增、刪除
- 能監(jiān)聽數(shù)組索引、
length變化 - 支持
Map/Set等原生數(shù)據(jù)結(jié)構(gòu) - 按需追蹤屬性,性能更好
缺點(diǎn):
- 需要現(xiàn)代瀏覽器或 ES2015+ 環(huán)境支持
2. 對數(shù)組、對象、Map/Set 的支持
| 特性 | Vue 2 | Vue 3 |
|---|---|---|
| 新增/刪除對象屬性 | ? 需用 Vue.set / Vue.delete | ? 直接生效 |
| 數(shù)組索引修改 | ? 需用 Vue.set | ? 直接生效 |
| 數(shù)組 length 修改 | ? 無法直接監(jiān)聽 | ? 支持 |
| Map / Set | ? 不支持 | ? 完全支持 |
- 在 Vue 2 中:
this.arr[1] = 10; // 無法觸發(fā)更新 Vue.set(this.arr, 1, 10); // 才能觸發(fā)視圖更新
- 在 Vue 3 中:
this.arr[1] = 10; // 直接觸發(fā)更新
3. 性能對比
- Vue 2:初始化時遞歸遍歷整個數(shù)據(jù)對象,即使某個屬性永遠(yuǎn)不用,也會被劫持。大數(shù)據(jù)對象場景下會影響性能。
- Vue 3:按需追蹤,只有訪問到的屬性才會被收集依賴,減少無用監(jiān)聽,提高運(yùn)行效率。
4. 新 API 的支持
- Vue 3 引入了 組合式 API,提供了
ref、reactive、computed、watchEffect等響應(yīng)式函數(shù),讓開發(fā)者可以在邏輯復(fù)用和類型推斷方面更加靈活。 - Vue 2 原生只有 Options API,要想用類似 API,需要引入 Vue Composition API 插件。
5. TypeScript 友好度
- Vue 2:類型推斷不夠友好,復(fù)雜對象可能需要手動聲明類型。
- Vue 3:
Proxy讓類型推斷更自然,配合組合式 API,TypeScript 體驗提升明顯。
6. 總結(jié)對比表
| 特性 | Vue 2 (Object.defineProperty) | Vue 3 (Proxy) |
|---|---|---|
| 新增/刪除屬性監(jiān)聽 | ? | ? |
| 數(shù)組索引監(jiān)聽 | ? | ? |
| 數(shù)組 length 監(jiān)聽 | ? | ? |
| Map/Set 響應(yīng)式 | ? | ? |
| 初始化性能 | 較慢,遞歸遍歷 | 較快,按需追蹤 |
| TypeScript 友好度 | 一般 | 很好 |
7. 可視化原理圖
- Vue 2 響應(yīng)式機(jī)制簡圖:
data -> 遍歷每個屬性 -> defineProperty(getter/setter) 讀取屬性 -> 收集依賴 修改屬性 -> 通知視圖更新
- Vue 3 響應(yīng)式機(jī)制簡圖:
data -> Proxy 代理整個對象 讀取任意屬性 -> 收集依賴 修改/新增/刪除屬性 -> 通知視圖更新
8. 寫在最后
Vue 3 的響應(yīng)式系統(tǒng)幾乎解決了 Vue 2 的所有痛點(diǎn),同時性能和可維護(hù)性都更好。
如果你的項目需要長期維護(hù),并且運(yùn)行環(huán)境允許,建議直接使用 Vue 3,享受它帶來的更優(yōu)雅的響應(yīng)式體驗。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue中img src 動態(tài)加載本地json的圖片路徑寫法
這篇文章主要介紹了vue中的img src 動態(tài)加載本地json的圖片路徑寫法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04
antd-日歷組件,前后禁止選擇,只能選中間一部分的實(shí)例
這篇文章主要介紹了antd-日歷組件,前后禁止選擇,只能選中間一部分的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
VuePress在build打包時window?document?is?not?defined問題解決
這篇文章主要為大家介紹了VuePress在build打包時window?document?is?not?defined問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07

