首頁  >  文章  >  web前端  >  vue3 reactive響應式依賴收集派發更新原理是什麼

vue3 reactive響應式依賴收集派發更新原理是什麼

王林
王林轉載
2023-05-16 19:28:201118瀏覽

    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刪除