Maison  >  Article  >  interface Web  >  Quel est le principe de la collecte, de la répartition et de la mise à jour des dépendances réactives de vue3 ?

Quel est le principe de la collecte, de la répartition et de la mise à jour des dépendances réactives de vue3 ?

王林
王林avant
2023-05-16 19:28:201071parcourir

    proxy

    vue3 a été modifié de Object.property à Proxy Par rapport au premier, Proxy peut surveiller directement le. tableau d'objets. Pour les objets et les tableaux de niveau profond, le déclencheur sera mappé à getter, puis collectera récursivement les dépendances. Ce n'est pas directement récursif comme la violence de vue2. les performances sont meilleures. 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

    • Détournez le proxy de l'objet transmis par réactif et effectuez des opérations de collecte de dépendances et de mise à jour de notification en interne🎜
    • 🎜
      function trigger(target, key) {
        let depsMap = targetMap.get(target);
        let dep = depsMap.get(key);
        for (let effect of dep) {
          effect.fn();
        }
      }
      🎜Utilisez Reflet Effectuez des opérations standardisées sur les objets, car si JS échoue directement, aucune exception ne sera générée🎜🎜De cette façon, la collecte des dépendances est effectuée après l'obtention des données et les mises à jour des dépendances sont notifiées après la mise à jour des données🎜 🎜Collection de dépendances🎜🎜 Ensuite, nous présenterons à quoi ressemble la collection de dépendances🎜rrreee🎜Tout d'abord, il s'agit d'une WeakMap-->Ensuite, l'utilisateur obtient la carte interne correspondante via la cible-->Ensuite, la collection Set est obtenue via la clé et les dépendances internes sont stockées une par une. En fait, c'est le processus de collecte de dépendances. 🎜🎜La raison pour laquelle WeakMap est utilisé ici est qu'il s'agit d'une référence faible et n'affectera pas le mécanisme de récupération de place. 🎜<h4>currentEffect</h4>🎜Alors, qu'est-ce que <code>currentEffect exactement ? En fait, c'est la classe en cours d'exécution dans ReactiveEffect 🎜rrreee🎜 qui sera expliquée en détail plus tard, pour l'instant, elle peut être comprise comme une dépendance Une fois que l'utilisateur a utilisé la fonction d'effet, les données réactives à l'intérieur. va changer. Réexécutez la fonction de rappel passée 🎜🎜Les dépendances collectées dans vue2 correspondent aux observateurs, et les dépendances collectées dans vue3 sont en fait des effets. Les fonctions qu'elles implémentent sont en fait les mêmes. 🎜🎜Distribuer les mises à jour🎜🎜Ignorez le problème du DOM pour l'instant L'opération est en fait très simple, utilisez simplement la cible et le détournés par le <code>Proxy<.> key</.> trouve la collection Set correspondante et appelle la fonction fn passée par l'utilisateur pour mettre à jour les dépendances🎜rrreee

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer