vue3的响应式是基于proxy的。
class Dep{
constructor(){
this.subscriber = new Set()
}
// addEffect(effect){
// this.subscriber.add(effect)
// }
depend(){
if(activeEffect) {
this.subscriber.add(activeEffect)
}
}
notify(){
this.subscriber.forEach(effect => {
effect()
})
}
}
let activeEffect = null;
function watchEffect(effect){
// dep.addEffect(effect)
activeEffect = effect;
// dep.depend();
effect();
activeEffect = null;
}
const targetMap = new WeakMap()
function getDep(target, key){
let depsMap = targetMap.get(target)
if(!depsMap) {
depsMap = new Map();
targetMap.set(target, depsMap)
}
let dep = depsMap.get(key);
if(!dep) {
dep = new Dep();
depsMap.set(key, dep)
}
return dep
}
function reactive(raw){
return new Proxy(raw, {
get(target, key) {
const dep = getDep(target, key)
dep.depend();
return target[key]
},
set(target, key, newValue) {
const dep = getDep(target, key);
target[key] = newValue;
dep.notify()
}
})
}
let info = reactive({name: 'coderwhy', age: 18, counter: 100})
let foo = reactive({height: 1.88});
// const dep = new Dep()
watchEffect(function (){
console.log(info.counter * 2, info.age)
})
watchEffect(function (){
console.log(info.counter * info.counter)
})
watchEffect(function (){
console.log(foo.height)
})
// info.counter++;
// foo.height = 2
// dep.notify()
info.age++