首页 > web前端 > Vue.js > 正文

vue3 reactive响应式依赖收集派发更新原理是什么

王林
发布: 2023-05-16 19:28:20
转载
1131 人浏览过

    proxy

    vue3已经从Object.property更换成ProxyProxy相比于前者可以直接监听对象数组,对于深层次的对象和数组,会把触发对应getter,然后去递归进行依赖收集,并不是直接像vue2暴力那样递归,总体而言性能更好

    • 对reactive传进来的对象进行Proxy进行劫持在内部进行依赖收集与通知更新操作

    function reactive(raw) {
      return new Proxy(raw, {
        get(target, key) {
          const res = Reflect.get(target, key);
          //添加依赖
          track(target, key as string);
          return res;
        },
        set(target, key, value) {
          const res = Reflect.set(target, key, value);
          trigger(target, key);
          return res;
        },
      });
    }
    登录后复制

    采用Reflet对对象进行标准化操作,因为如果直接采用JS如果失败了,不会产生异常提示

    这样在进行获取数据是后进行依赖收集,在更新数据后进行通知依赖更新

    依赖收集

    接下来便介绍依赖收集是个什么样子

    const targetMap = new WeakMap();
    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(currentEffect);
    }
    登录后复制

    首先是一个WeakMap-->然后用户通过target获取对应的内部Map-->然后通过key获取到Set集合,内部便是存储的一个个依赖。其实依赖收集的过程就是这样。

    这里使用WeakMap原因是它是一个弱引用,不会影响垃圾回收机制回收。

    currentEffect

    那么currentEffect 到底是个什么东西呢?实际上是ReactiveEffect中正在运行的类

    class ReactiveEffect {
      private fn: Function;
      constructor(_fn: Function) {
        this.fn = _fn;
      }
      run() {
        currentEffect = this;
        this.fn();
      }
    }
    let currentEffect: null | ReactiveEffect = null;
    function effect(fn: Function) {
      const reactiveEffect = new ReactiveEffect(fn);
      reactiveEffect.run();
    }
    登录后复制

    后续会详情讲解,目前可以就把他理解成一个依赖,用户使用了effect函数过后,里面的响应式数据发生变化后会重新执行传递进去的回调函数

    vue2中收集的依赖对应watcher,vue3收集的依赖实际是effect,他们两者实现功能实际上是一样的。

    派发更新

    这里暂不考虑DOM问题,操作起来其实很简单就是通过被Proxy劫持的targetkey找到对应的Set集合调用用户传递的fn函数进行依赖更新

    function trigger(target, key) {
      let depsMap = targetMap.get(target);
      let dep = depsMap.get(key);
      for (let effect of dep) {
        effect.fn();
      }
    }
    登录后复制

    以上是vue3 reactive响应式依赖收集派发更新原理是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

    相关标签:
    来源:yisu.com
    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板