Vue響應(yīng)式系統(tǒng)的依賴收集追蹤原理

訂閱者 Dep

首先實(shí)現(xiàn)一個(gè)訂閱者Dep,它的主要作用是用來(lái)存放watcher觀察者對(duì)象

  class Dep {
    constructor () {
    /*用來(lái)存放watcher對(duì)象的數(shù)組*/
      this.subs = [];
    }

    /*在subs中添加一個(gè)Watcher對(duì)象*/
    addSub (sub) {
      this.subs.push(sub);
    }

    /*通知所有watcher對(duì)象更新視圖*/
    notify () {
      this.subs.forEach((sub) => {
          sub.update();
      });
    }
  }

觀察者 Watcher

  class Watcher {
    constructor () {
      /* 在new一個(gè)Watcher對(duì)象時(shí)將該對(duì)象賦值給Dep.target,在get中會(huì)用到 */
      Dep.target = this;
    }

    /* 更新視圖的方法 */
    update () {
        console.log('視圖更新了');
    }
  }
  Dep.target = null;

依賴收集

接下來(lái)修改一下defineReactive以及Vue的構(gòu)造函數(shù),來(lái)完成依賴收集。

  function defineReactive(obj, key, val) {
      const dep = new Dep();
      Object.defineProperty(obj, key, {
          enumerable:  true,
          configurable:  true,
          get: function reactiveGetter () {
               /* 將Dep.target(即當(dāng)前的Watcher對(duì)象存入dep的subs中) */
              dep.addSub(Dep.target);
              return val;
          },
          set: function reactiveSetter (newVal) {
              if (newVal === val) {
                return;
              }
              /* 在set的時(shí)候觸發(fā)dep的notify來(lái)通知所有的Watcher對(duì)象更新視圖 */
              dep.notify();
          }
      });
  }
   
  class Vue {
      constructor (options) {
          this._data = options.data;
          observer(this._data);
          /* 新建一個(gè)Watcher觀察者對(duì)象,這時(shí)候Dep.target會(huì)指向這個(gè)Watcher對(duì)象 */
          new Watcher();
          /* 在這里模擬render的過(guò)程,為了觸發(fā)test屬性的get函數(shù) */
          console.log('render', this._data.test);
      }
   }

小結(jié)

首先在observer的過(guò)程中會(huì)注冊(cè)get方法,該方法用來(lái)進(jìn)行依賴收集。在它的閉包中會(huì)有一個(gè)Dep對(duì)象,這個(gè)對(duì)象用來(lái)存放Watcher對(duì)象的實(shí)例。其實(shí)依賴收集的過(guò)程就是把watcher實(shí)例存放到對(duì)應(yīng)的Dep對(duì)象中去。get方法可以讓當(dāng)前的watcher對(duì)象(Dep.target)存放到它的subs中(通過(guò)addSub方法)。在數(shù)據(jù)發(fā)生變化時(shí),set會(huì)調(diào)用Dep對(duì)象的notify方法通知它內(nèi)部的watcher對(duì)象進(jìn)行視圖更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容