共计 1190 个字符,预计需要花费 3 分钟才能阅读完成。
实现 effect & reactive 依赖收集 & 触发依赖
创立 effect.spec.ts 单测
import {reactive} from "../reactive"
import {effect} from "../effect"
describe('effect', () => {it('happy path', () => {
const user = reactive({age: 10,})
let nextAge
effect(() => {nextAge = user.age + 1})
expect(nextAge).toBe(11)
// update
user.age++
expect(nextAge).toBe(12)
})
})
//effect.ts
class ReactiveEffect{
private _fn
constructor(fn){this._fn = fn}
run(){
activeEffect = this
this._fn()}
}
export function effect(fn){const _effect = new ReactiveEffect(fn)
_effect.run()}
let activeEffect
const targetMap = new WeakMap()
// 收集依赖
export function track(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 Set()
depsMap.set(key,dep)
}
// 判断是否曾经收集过依赖,没有就间接增加
dep.add(activeEffect)
}
// 触发依赖
export function trigger(target, key){let depsMap = targetMap.get(target)
let deps = depsMap.get(key)
console.log(deps)
for(const effect of deps){effect.run()
}
}
//reactive.ts
import {track,trigger} from "./effect"
export function reactive(raw){
return new Proxy(raw,{get(target,key){const res = Reflect.get(target,key)
// 设置依赖
track(target, key)
return res
},
set(target,key,value){const res = Reflect.set(target,key,value)
// 触发依赖
trigger(target, key)
return res
}
})
}
执行 yarn test effect
失去
正文完