// 保存当前要收集的函数
let activeReactiveFn = null
// 每个响应式数据都需要的依赖
class Depend {
constructor() {
// 把搜集到的函数放在一个Set里,可以去除重复的函数
this.collect = new Set()
}
// 添加依赖
addDepend() {
if(activeReactiveFn) {
this.collect.add(activeReactiveFn)
}
}
// 当给响应式数据赋值时,将收集的函数依次执行
notify() {
this.collect.forEach(fn => {
fn()
})
}
}
// 需要被收集的函数都需要watch一下,内部会根据取值自动分配给自己的Depend
function watch(fn) {
activeReactiveFn = fn
fn()
activeReactiveFn = null
}
// 将普通对象设置一个代理
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) {
const depend = getDepend(target,key)
// 当数据变化时,执行依赖
depend.notify()
Reflect.set(target,key,newValue,receiver)
}
})
}
const targetMap = new WeakMap()
// 根据传过来的对象和key,获取对应的Depend
function getDepend(target,key) {
let map = targetMap.get(target)
if(!map) {
map = new Map()
targetMap.set(target,map)
}
let depend = map.get(key)
if(!depend) {
depend = new Depend()
map.set(key,depend)
}
return depend
}
const obj = {
name:'liuqi',
age:18
}
const objProxy = reactive(obj)
function consoleObjName() {
console.log('consoleObjName',objProxy.name)
}
function consoleObjAge() {
console.log('consoleObjAge',objProxy.age,objProxy.name)
}
watch(consoleObjName)
watch(consoleObjAge)
objProxy.name = 'why'
// objProxy.age = 20