Vue3 响应式源码实现
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const depend = getDepend(target, key);
depend.addDepend();
return Reflect.get(target, key, receiver);
},
set(target, key, newValue, receiver) {
console.log(`对象的${key}值改变为了${newValue}`);
Reflect.set(target, key, newValue, receiver);
const depend = getDepend(target, key);
depend.notify();
},
});
}
let curDepsFunc = null;
class Deps {
constructor() {
this.dep = new Set();
}
addDepend() {
if (curDepsFunc) {
this.dep.add(curDepsFunc);
}
}
notify() {
for (const fn of this.dep) {
fn();
}
}
}
const dependWeakMap = new WeakMap();
function getDepend(target, key) {
let depsMap = dependWeakMap.get(target);
if (!depsMap) {
depsMap = new Map();
dependWeakMap.set(target, depsMap);
}
let deps = depsMap.get(key);
if (!deps) {
deps = new Deps();
depsMap.set(key, deps);
}
return deps;
}
function watchEffect(fn) {
curDepsFunc = fn;
fn();
}
const proxyObj = reactive({
name: 'Kobe',
age: 18,
});
watchEffect(function () {
console.log(proxyObj.name);
console.log(proxyObj.age);
});
// watchEffect(function () {
// console.log(proxyObj.age);
// });
proxyObj.name = 'wangweiping';
proxyObj.name = 'xieting';
proxyObj.age = 2012;