>웹 프론트엔드 >View.js >vue3 반응형 응답 종속성 수집, 전달 및 업데이트의 원칙은 무엇입니까?

vue3 반응형 응답 종속성 수집, 전달 및 업데이트의 원칙은 무엇입니까?

王林
王林앞으로
2023-05-16 19:28:201136검색

    proxy

    vue3이 Object.property에서 Proxy로 변경되었습니다. 이전에 비해 Proxy는 직접 모니터링할 수 있습니다. 객체 배열. 심층 객체 및 배열의 ​​경우 트리거는 getter에 매핑된 다음 재귀적으로 종속성을 수집합니다. 전체적으로는 폭력입니다. 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

    • Reactive로 전달된 객체의 프록시를 탈취하고 내부적으로 종속성 수집 및 알림 업데이트 작업을 수행하세요🎜
    • 🎜
      function trigger(target, key) {
        let depsMap = targetMap.get(target);
        let dep = depsMap.get(key);
        for (let effect of dep) {
          effect.fn();
        }
      }
      🎜사용하세요. Reflet JS가 직접 실패하면 예외가 발생하지 않기 때문에 객체에 대해 표준화된 작업을 수행합니다.🎜🎜이런 방식으로 데이터를 얻은 후 종속성 수집을 수행하고 데이터가 업데이트된 후에 종속성 업데이트를 알립니다. 🎜🎜Dependency collection🎜🎜 다음으로, dependency collection이 어떤 모습인지 소개하겠습니다🎜rrreee🎜먼저 WeakMap입니다.-->사용자는 타겟을 통해 해당 내부 Map을 얻습니다-->Set 컬렉션을 얻습니다. 키를 통해 내부 종속성이 하나씩 저장됩니다. 실제로 이것이 종속성 수집 프로세스입니다. 🎜🎜여기서 WeakMap을 사용하는 이유는 약한 참조이고 가비지 수집 메커니즘에 영향을 주지 않기 때문입니다. 🎜

      currentEffect

      🎜그럼 currentEffect는 정확히 무엇인가요? 실제로는 ReactiveEffect에서 실행되는 클래스입니다. 🎜rrreee🎜는 나중에 자세히 설명하겠습니다. 지금은 사용자가 효과 기능을 사용한 후 내부의 반응형 데이터가 변경되는 것으로 이해하면 됩니다. . 전달된 콜백 함수를 다시 실행하세요. 🎜🎜vue2에서 수집된 종속성은 감시자에 해당하며, vue3에서 수집된 종속성은 실제로 구현되는 함수와 동일합니다. 🎜🎜업데이트 배포🎜🎜지금은 DOM 문제를 무시하세요. 작업은 실제로 매우 간단합니다. Proxytarget를 사용하면 됩니다. /code> 키는 해당 Set 컬렉션을 찾고 사용자가 전달한 fn 함수를 호출하여 종속성을 업데이트합니다🎜rrreee

    위 내용은 vue3 반응형 응답 종속성 수집, 전달 및 업데이트의 원칙은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제