let currentEffect;
class Dep {
constructor(value) {
this.deps = new Set();
this._value = value;
}
get value() {
this.depend()
return this._value
}
set value(val) {
this._value = val;
this.notice()
}
depend() {
if (currentEffect) {
this.deps.add(currentEffect)
}
}
notice() {
this.deps.forEach(effect => {
effect()
})
}
}
function ref(Raw) {
const dep = new Dep(Raw)
return {
get value() {
return dep.value
},
set value(val) {
dep.value = val
}
}
}
function effectWatch(effect) {
currentEffect = effect;
effect();
currentEffect = null;
}
const targetDeps = new Map()
function getDep(target, key) {
let deps = targetDeps.get(target);
if (!deps) {
deps = new Map()
targetDeps.set(target, deps)
}
let dep = deps.get(key);
if (!dep) {
dep = new Dep(target[key])
deps.set(key, dep)
}
return dep
}
function reactive(Raw) {
return new Proxy(Raw, {
get(target, key) {
if (typeof target[key] === "object") {
return reactive(target[key])
}
const dep = getDep(target, key)
dep.depend()
return Reflect.get(target, key)
},
set(target, key, value) {
if (typeof target[key] === "object") {
return reactive(target[key])
}
const dep = getDep(target, key)
const result = Reflect.set(target, key, value)
dep.notice()
return result
}
})
}
const obj = {
zhangsan: {
age: 10,
gender: {
age: 19
}
}
}
const user = reactive(obj);
let b, c;
effectWatch(() => {
b = user.zhangsan.gender.age + 100;
console.log("b", b)
c = user.zhangsan.age
console.log("c", c)
})
user.zhangsan.age = 15