vue3响应式原理-effect

sin信仰

关注

阅读 46

2022-04-05

  1. 为了实现响应式,我们使用了new Proxy
  2. effect默认数据变化要能更新,我们先将正在执行的effect作为全局变量,渲染(取值),然后在get方法中进行依赖收集
  3. 依赖收集的数据格式weakMap(对象:map(属性:set(effect))
  4. 用户数据发生变化,会通过对象属性来查找对应的effect集合,全部执行;
  5. 调度器的实现,创建effect时,把scheduler存在实例上,调用runner时,判断如果有调度器就调用调度器,否则执行runner

边界情况:

  1. 如果在执行effect时,又修改了这个effect的依赖,会出现递归调用,所以在trigger中遍历执行effect时,要判断将要执行的effect不是activeEffect;
export function trigger(target, type, key, value, oldValue) {
    const depsMap = targetMap.get(target);
    if (!depsMap) return;
    let effects = depsMap.get(key);
    if (effects) {
        effects = new Set(effects);
        effects.forEach((effect) => {
            if (effect !== activeEffect) {
                if (effect.scheduler) {
                    effect.scheduler();
                } else {
                    effect.run();
                }
            }
        });
    }
}
  1. 如果effect存在分支情况,会导致不需要的依赖仍然存在,所以每次执行effect的回调时,要清空当前的effect.deps,把依赖全部删除,这样执行回调的时候重新收集依赖,就可以保证effect依赖的正确;

  2. 执行删除时,要注意需要将依赖的set删除,而不是直接把数组长度设置为0,另外为了防止一边删除一边新增,导致死循环,在执行时,需要先把原来的数组保存一份,遍历保存后的数组;

精彩评论(0)

0 0 举报