就在昨天Vue 3的源碼公佈了,在此以前相信對Vue有了解的開發者都知道Vue 3會改用Proxy
來代替Object.defineProperty
實現數據響應。至於爲何要用Proxy
,你們從去年年末到如今這段時間多多少少都有了解過了吧。這兩天都在看Vue 3相關的東西,此文旨在鞏固用Proxy
實現響應數據的過程,以便更好理解源碼的實現。javascript
const toProxy = new WeakMap();
const toRaw = new WeakMap();
// toProxy、toRaw都是用於存放代理過的對象的哈希表,防止重複代理
function upDate() { // 至關於vue數據更新後執行的操做
console.log('數據更新');
}
function isObject(target) {
return typeof target === 'object' && target !== null;
}
function reactive(target) {
if (!isObject(target)) { // 若是不是對象就直接返回
return target;
}
if (toProxy.get(target)) { // 若是代理表中已經存在,就把這個結果返回
return toProxy.get(target);
}
if (toRaw.has(target)) { // 若是這個對象已經被代理了,就把對象返回
return target;
}
const handlers = {
get(target, key, receiver) {
let res = Reflect.get(target, key, receiver);
if(isObject(target[key])){
return reactive(res); // 遞歸
}
return res;
},
set(target, key, value, receiver) {
if (!target.hasOwnProperty(key)) {
upDate();
}
return Reflect.set(target, key, value, receiver);
},
deleteProperty(target, key) {
return Reflect.defineProperty(target, key);
}
}
let observed = new Proxy(target, handlers);
toProxy.set(target, observed); // target是原對象,存放原對象代理後的結果
toRaw.set(observed, target); // target是已經代理過的對象
return observed;
}
let obj = {
name: 'Vue 3'
}
let vueData = reactive(obj);
vueData.name = '1'
複製代碼
上述代碼就實現了數據響應,看完這些,再去看源碼中的reactive.ts
應該就很清晰了,原理是一致的,這裏就大概是缺了數據變化的依賴收集和執行,還有部分拓展。vue