目錄
- 簡介
- Vue2 響應式
- Vue2 響應式的局限性
- Vue3 響應式
- Vue3 響應式的優點
- Vue2 和 Vue3 響應式對比
簡介
在 Vue 框架中,數據的響應式是其核心特性之一。當頁面數據發生變化時,我們希望界面能自動更新,而不是手動操作 DOM。這就需要對數據進行監聽,并在數據變更時觸發 UI 重新渲染。
Vue2 和 Vue3 在實現響應式的方式上有所不同,Vue2 主要依賴 Object.defineProperty
,而 Vue3 則引入了 Proxy
,大大優化了響應式系統的性能和靈活性。它們都是通過函數來封裝響應式對象,方便讀取或更新數據時能夠進行其他的操作。
Vue2 響應式
Vue2 使用 Object.defineProperty
來攔截對象屬性的訪問和修改,從而實現響應式。
const obj = {a: 1,b: 2,c: {x: 66,y: 2,}
}function isObject(v) {return typeof v === 'object' && v !== null;
}function observe(obj) {for (const k in obj) {let v = obj[k];if (isObject(v)) observe(v); // 遞歸遍歷Object.defineProperty(obj, k, {get() {console.log(`讀取${k}, 值${v}`);return v;},set(newVal) {v = newVal;console.log(`更新${k}, 值${v}`);}});}
}observe(obj);obj.a;
obj.a = 101;
obj.c.x;
obj.c.x = 166;
Vue2 響應式的局限性
- 需要遍歷對象的每個屬性,性能較低。
- 不能檢測到新增或刪除的屬性。
- 需要手動調用
Vue.set()
以確保新屬性的響應式。
Vue3 響應式
Vue3 使用 Proxy
實現響應式,可以直接監聽整個對象,而不是逐個屬性。
const obj = {a: 1,b: 2,c: {x: 1,y: 2,}
};function isObject(v) {return typeof v === 'object' && v !== null;
}function reactive(target) {return new Proxy(target, {get(target, k) {console.log(`讀取: ${k}, 值: ${target[k]}`);// 讀取時才遞歸生成代理if (isObject(target[k])) return reactive(target[k]);return target[k];},set(target, k, newVal) {if (newVal === target[k]) return;console.log(`更新: ${k}, 值${newVal}`);target[k] = newVal;return true;}});
}const proxy = reactive(obj);proxy.a;
proxy.a = 100;
proxy.c.x;
Vue3 響應式的優點
- 直接監聽整個對象,無需遍歷所有屬性。
- 可以檢測到屬性的新增和刪除。
- 具有更好的性能和更簡潔的代碼結構。
Vue2 和 Vue3 響應式對比
對比項 | Vue2 (Object.defineProperty ) | Vue3 (Proxy ) |
---|---|---|
監聽方式 | 逐個屬性攔截 | 整個對象攔截 |
深度監聽 | 需要遞歸處理 | 訪問時自動代理 |
屬性新增刪除 | 需要 Vue.set() 處理 | 可直接監聽 |
數組監聽 | 需要重寫數組方法 | 原生支持 |
性能 | 需要遍歷所有屬性,較低 | 直接代理整個對象,更高 |
兼容性 | 兼容性好,支持 ES5 及以上 | 需要 ES6 Proxy 支持 |
Vue3 通過 Proxy
解決了 Vue2 的許多缺陷,使得響應式系統更加高效、靈活和簡潔。因此,Vue3 的響應式能力遠超 Vue2。