參考資料:vue打包后的源碼
學(xué)習(xí)方法:瀏覽器調(diào)試
使用的測試案例:
(一個模板對應(yīng)一個renderWatcher,一個renderWatcher對應(yīng)一個render function )
(data中的一個屬性對應(yīng)一個dep 例如 message對應(yīng)dep(message)a對應(yīng)dep(a)b對應(yīng)dep(b))
(computed不對應(yīng)dep)
<div>{{message}} {{a}} {{c}} {{a}} {段标}</div>
data: {
message: 1,
a: 1,
b: 2
}
computed: {
c () {
return this.a + this.b + 22
}
}
listeners進(jìn)行數(shù)據(jù)響應(yīng)式
然后將computed中的屬性進(jìn)行響應(yīng)式 并且為computed中的每一個屬性生成一個computedWatcher對象【一個屬性c對應(yīng)一個computedWatcher對象】涯冠、并為該屬性生成一個getter方法[c () {return this.a + this.b + 22}] 并將該屬性進(jìn)行數(shù)據(jù)響應(yīng)式
程序往下執(zhí)行,然后會一個new renderWatcher()
watcher的實例化過程會調(diào)用vm._update(vm._render())怀樟,
其中,vm._render會生成一個render函數(shù)盆佣,render函數(shù)執(zhí)行的時候會獲取指令模板中的值往堡,進(jìn)而觸發(fā)各個屬性(message a b c)的getter方法
getter方法中一方面獲取到了值,另一方面完成了依賴搜集
message屬性的getter觸發(fā) dep(message) [renderWatcher]
a屬性的getter觸發(fā)dep(a) [renderWatcher]
b屬性的getter觸發(fā)dep(b) [renderWatcher]
c屬性的getter會執(zhí)行this.a + this.b + 22 會調(diào)用a屬性的getter和b屬性的getter
進(jìn)而使得
dep(a) [renderWatcher computedWatcher(c)]
dep(b) [renderWatcher computedWatcher(c)]
render函數(shù)獲取完值之后共耍,生成了vnode對象
調(diào)用vm._update(vnode) 進(jìn)而調(diào)用vm.patch 完成視圖的更新
==================================================================
當(dāng)a的值發(fā)生改變時虑灰,
會觸發(fā)dep(a) .notify
進(jìn)而使得renderWatcher和computedWatcher進(jìn)行處理(執(zhí)行wathcer的update函數(shù))
renderWatcher會進(jìn)入到queueWatcher隊列中,交由異步隊列處理
computedWatcher會 if (watcher.lazy) watcher.dirty = true;將dirty設(shè)置為true
然后開始執(zhí)行異步隊列痹兜,進(jìn)而執(zhí)行renderWatcher.run()穆咐,進(jìn)而調(diào)用vm._update(vm._render()) 后續(xù)過程同前文描述 【 這后面的過程還會去調(diào)用computedWatcher的getter函數(shù)獲取值,這個時候重新進(jìn)行依賴收集字旭,數(shù)據(jù)更新】