实现 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.tsclass 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 activeEffectconst 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.tsimport { 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
失去