Vue響應(yīng)式原理Observer昙啄、Dep梳凛、Watcher理解

Vue響應(yīng)式原理Observer梳杏、Dep掰读、Watcher理解

  1. Observer
  • Observer是用來給數(shù)據(jù)添加Dep依賴蹈集。
class Observer {
  constructor() {
    // 響應(yīng)式綁定數(shù)據(jù)通過方法
    observe(this.data);
  }
}

export function observe (data) {
  const keys = Object.keys(data);
  for (let i = 0; i < keys.length; i++) {
    // 將data中我們定義的每個屬性進(jìn)行響應(yīng)式綁定
    defineReactive(obj, keys[i]);
  }
}
  1. Dep 管理依賴
  • Dep是data每個對象包括子對象都擁有一個該對象, 當(dāng)所綁定的數(shù)據(jù)有變更時, 通過dep.notify()通知Watcher拢肆。

  • Dep就是幫我們收集【究竟要通知到哪里的】靖诗。

    <div>
      <p>{{message}}</p>
    </div>
    
    data: {
      text: 'hello world',
      message: 'hello vue',
    }
    
    1. 雖然data中有text和message屬性刊橘,但是只有message被渲染到頁面上,至于text無論怎么變化都影響不到視圖的展示攒庵,因此我們僅僅對message進(jìn)行收集即可败晴,可以避免一些無用的工作。
    2. 當(dāng)使用watch屬性時稳懒,也就是開發(fā)者自定義的監(jiān)聽某個data中屬性的變化慢味。比如監(jiān)聽message的變化纯路,message變化時我們就要通知到watch這個鉤子,讓它去執(zhí)行回調(diào)函數(shù)装哆。定嗓,第二個依賴就是用來管理watch中message變化的。
    3. 這個時候message的Dep就收集到了兩個依賴
      • 依賴1: data中message的變化
      • 依賴2: watch監(jiān)聽message的變化
    watch: {
      message: function (val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal)
      },
    }    
    
    1. 開發(fā)者自定義computed計(jì)算屬性時凌简,如下 messageTransfer 屬性雏搂,是依賴message的變化的。因此message變化時我們也要通知到computed凸郑,讓它去執(zhí)行回調(diào)函數(shù)。 這個時候message的Dep就收集到了三個依賴诲祸,這個依賴就是用來管理computed中message變化的而昨。

      computed: {
        messageTransfer() {
          return this.message.split('').reverse().join('');
        }
      }
      
    2. 圖示如下:一個屬性可能有多個依賴歌憨,每個響應(yīng)式數(shù)據(jù)都有一個Dep來管理它的依賴。

      image.png

  1. Watcher
  • Watcher是連接Observer和Compile的橋梁甲抖,Compile解析指令時會創(chuàng)建一個對應(yīng)的Watcher并綁定update方法 , 添加到Dep對象上惧眠。

Dep 如何收集依賴

  1. Object.defineProperty
    function defineReactive (obj, key, val) {
      let Dep; // 依賴
    
      Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: () => {
          console.log('我被讀了于个,我要不要做點(diǎn)什么好?');
          // 被讀取了厅篓,將這個依賴收集起來
          Dep.depend(); // 本次新增
          return val;
        },
        set: newVal => {
          if (val === newVal) {
            return;
          }
          val = newVal;
          // 被改變了捶码,通知依賴去更新
          Dep.notify(); // 本次新增
          console.log("數(shù)據(jù)被改變了,通知所有的wather去調(diào)用update!");
        }
      })
    }
    

什么是依賴 ? (Watcher)

  1. Watcher就是類似觀察者的角色档押,比如message就有三個觀察者祈纯,當(dāng)message變化,就通知這三個觀察者粒没,他們就去執(zhí)行各自需要做的變化 watcher.update()簇爆。

  2. 可以推測出爽撒,Watcher必須要有的2個方法硕勿。一個就是通知變化厕妖,另一個就是被收集起來到Dep中去。

    class Watcher {
      addDep() {
        // 我這個Watcher要被Observer塞到Dep里去了~~
      },
      update() {
        // Dep通知我更新呢~~
      }, 
    }
    

總結(jié)

  1. Vue響應(yīng)式原理的核心就是Observer软能、Dep举畸、Watcher。

  2. Observer中進(jìn)行響應(yīng)式的綁定跋核,在數(shù)據(jù)被讀的時候砂代,觸發(fā)get方法,執(zhí)行Dep來收集依賴刻伊,也就是收集Watcher椒功。

  3. 在數(shù)據(jù)被改的時候,觸發(fā)set方法丁屎,通過對應(yīng)的所有依賴(Watcher)旱眯,去執(zhí)行更新。比如watch和computed就執(zhí)行開發(fā)者自定義的回調(diào)方法共虑。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末看蚜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子供炎,更是在濱河造成了極大的恐慌,老刑警劉巖音诫,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竭钝,死亡現(xiàn)場離奇詭異,居然都是意外死亡卧波,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旦签,“玉大人,你說我怎么就攤上這事偿曙「岢玻” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵炭臭,是天一觀的道長袍辞。 經(jīng)常有香客問我常摧,道長落午,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任界拦,我火速辦了婚禮梗劫,結(jié)果婚禮上截碴,老公的妹妹穿的比我還像新娘蛉威。我一直安慰自己,他們只是感情好哲虾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布束凑。 她就那樣靜靜地躺著湘今,像睡著了一般剪菱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孝常,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天构灸,我揣著相機(jī)與錄音,去河邊找鬼喜颁。 笑死,一個胖子當(dāng)著我的面吹牛隔披,可吹牛的內(nèi)容都是我干的寂拆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鬓长,長吁一口氣:“原來是場噩夢啊……” “哼尝江!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起啤覆,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎易遣,沒想到半個月后嫌佑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屋摇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年揩魂,在試婚紗的時候發(fā)現(xiàn)自己被綠了炮温。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡倦挂,死狀恐怖方援,靈堂內(nèi)的尸體忽然破棺而出涛癌,到底是詐尸還是另有隱情,我是刑警寧澤拳话,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布弃衍,位于F島的核電站,受9級特大地震影響姜钳,放射性物質(zhì)發(fā)生泄漏形耗。R本人自食惡果不足惜辙浑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望送滞。 院中可真熱鬧辱挥,春花似錦、人聲如沸晤碘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽童社。三九已至,卻和暖如春呀癣,著一層夾襖步出監(jiān)牢的瞬間十艾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工忘嫉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留案腺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓访递,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拷姿。 傳聞我的和親對象是個殘疾皇子响巢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容