diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index b593b86..59eac4a 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -1,3 +1,13 @@ +type KeyToDepMap = Map +/** + * 收集所有依赖的WeakMap实例 + * key: 响应性对象 + * value: Map对象 + * key: 响应性对象的指定属性 + * value:指定对象的指定属性的执行函数 + */ +const targetMap = new WeakMap() + export function effect(fn: () => T) { const _effect = new ReactiveEffect(fn) _effect.run() @@ -15,19 +25,38 @@ export class ReactiveEffect { /** * 收集依赖 - * @param target - * @param key + * @param target WeakMap的key + * @param key key代理对象的key, 当依赖被触发时,需要根据该key获取 */ export function track(target: object, key: unknown) { - console.log('收集依赖 track') + if (!activeEffect) return + //尝试从 targetMap 中, 根据target获取map + let depsMap = targetMap.get(target) + //如果获取到的map不存在,则生成新的map对象, 并把该对象赋值给对应的value + if (!depsMap) { + targetMap.set(target, (depsMap = new Map())) + } + //为指定map, 指定key, 设置回调函数 + depsMap.set(key, activeEffect) + console.log(targetMap) } /** * 触发依赖 - * @param target - * @param key - * @param newValue + * @param target WeakMap的key + * @param key key代理对象的key, 当依赖被触发时,需要根据该key获取 */ export function trigger(target: object, key: unknown, newValue: unknown) { - console.log('触发依赖 trigger') + //依据target获取存储的map实例 + const depsMap = targetMap.get(target) + if (!depsMap) { + return + } + //依据key, 从depsMap中取出value, 该value是一个ReactiveEffect类型的数据 + const effect = depsMap.get(key) as ReactiveEffect + if (!effect) { + return + } + //执行effect中保存的fn函数 + effect.fn() } diff --git a/packages/vue/examples/reactivity/reactive.html b/packages/vue/examples/reactivity/reactive.html index f23a65f..d232889 100644 --- a/packages/vue/examples/reactivity/reactive.html +++ b/packages/vue/examples/reactivity/reactive.html @@ -16,5 +16,8 @@ effect(()=>{ document.querySelector('#app').innerText=obj.name }) + setTimeout(()=>{ + obj.name='李四' + },2000) \ No newline at end of file