Vue雙向數據綁定的中心和基本api是Object.defineProperty,其內部真正介入數據雙向綁定流程的主要有Obderver、Dep和Watcher,基於defineProperty和發布者定閱者形式,終究完成數據的雙向綁定。那末Obderver、Dep和Watcher是怎樣詳細合營事情的呢?下面就來理一理。
看此文章之前你須要對vue的雙向數據綁定有肯定的明白。若不相識可移步:vue.js源碼解讀系列 – 雙向綁定詳細怎樣初始化和事情
看到這裏就當你對雙向數據綁定已經有肯定的明白:
提醒:要看懂此篇文章你須要對vue的mvvm有肯定的相識,並須要和專註的去明白,或許對比源碼隨着走,不然就很難真的看懂。
在這裏把雙向數據綁定分為兩個流程:
1、網絡依靠流程:
observe ->
walk ->
defineReactive ->
get ->
dep.depend() ->
watcher.addDep(new Dep()) ->
watcher.newDeps.push(dep) ->
dep.addSub(new Watcher()) ->
dep.subs.push(watcher)
依靠網絡會經由以上流程,終究watcher.newDeps數組中寄存dep列表,dep.subs數組中寄存watcher列表。
為何要舉行依靠網絡?
new Vue({
data(){
return {
name:'zane',
sex:'男'
}
}
})
有上面這個data,實際上頁面只運用到了name,並沒有運用age,依據Object.defineProperty的轉換,假如我們設置了this.sex=’女’,那末Vue也會去實行一遍假造DOM的比較,如許就無形的浪費了一些機能,因而才須要做依靠網絡,界面用到了就網絡,沒有用到就不網絡。
我們隨着流程走來理一遍源碼:
直接進入Object.defineProperty的get要領:
磨練你閉包才能的時刻到了,這個dep對象就是一個閉包。記下來我們看看dep.depend()要領的完成。
先停息一下,上面兩處都用到了 Dep.target ,我也說了它就是一個Watcher實例化對象,你是不是是很想搞懂它到底在那裡賦值的呢,不急請隨着我下面的代碼看看。
搞懂了Dep.target即是一個Watche對象,如今繼承回到之前的思緒看watcher.addDep做了什麼。
就如許依靠網絡的流程就走完了,是不是覺得很繞。
總結:依靠網絡終究在 watcher.newDeps 中push了閉包中傳過來的dep對象,在dep.subs中push了初始化Vue是簡歷的Watcher對象,這個對象的,this.getter = expOrFn,傳過來的expOrFn是後期數據更新頁面襯着的中心步驟,須要沉下心來好好去理理。
2、視圖更新流程:
set ->
dep.notify() ->
subs[i].update() ->
watcher.run() || queueWatcher(this) ->
watcher.get() || watcher.cb ->
watcher.getter() ->
vm._update() ->
vm.__patch__()
視圖更新會經由以上流程,終究挪用Vue的假造Dom diff歷程及時更新界面視圖
走到此處背面我就不去跟蹤了,背面會挪用vm.__patch__ 要領,進而實行假造DOM的diff歷程及時的更新界面。
總結:
要很好的明白vue的數據雙向綁定就要比較耐煩,沉下心來逐步明白,同時也須要對vue的源碼有個大抵的明白,不然你只會看的愈來愈焦躁愈來愈沒有自信心。
vue很好的利用了Object.defineProperty要領的 get和set要領,定閱者發布者的設想思緒,奇妙的構造代碼,值得我們很深切的去進修和明白,從而促使我們更好的去運用它。感謝尤大的無私奉獻,讓我們提高了生產力,把更多的精神花到營業邏輯中去。