摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過(guò)以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。
Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于defineProperty和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。那么Obderver、Dep和Watcher是如何具體配合工作的呢?下面就來(lái)理一理。
看此文章之前你需要對(duì)vue的雙向數(shù)據(jù)綁定有一定的理解。若不了解可移步:vue.js源碼解讀系列 - 雙向綁定具體如何初始化和工作
看到這里就當(dāng)你對(duì)雙向數(shù)據(jù)綁定已經(jīng)有一定的理解:
提示:要看懂此篇文章你需要對(duì)vue的mvvm有一定的了解,并需要和專注的去理解,或者對(duì)照源碼跟著走,不然就很難真的看懂。
在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程:
1、收集依賴流程:
</>復(fù)制代碼
observe ->
walk ->
defineReactive ->
get ->
dep.depend() ->
watcher.addDep(new Dep()) ->
watcher.newDeps.push(dep) ->
dep.addSub(new Watcher()) ->
dep.subs.push(watcher)
依賴收集會(huì)經(jīng)過(guò)以上流程,最終watcher.newDeps數(shù)組中存放dep列表,dep.subs數(shù)組中存放watcher列表。
為什么要進(jìn)行依賴收集?
</>復(fù)制代碼
new Vue({
data(){
return {
name:"zane",
sex:"男"
}
}
})
有上面這個(gè)data,實(shí)際上頁(yè)面只使用到了name,并沒(méi)有使用age,根據(jù)Object.defineProperty的轉(zhuǎn)換,如果我們?cè)O(shè)置了this.sex="女",那么Vue也會(huì)去執(zhí)行一遍虛擬DOM的比較,這樣就無(wú)形的浪費(fèi)了一些性能,因此才需要做依賴收集,界面用到了就收集,沒(méi)有用到就不收集。
我們跟著流程走來(lái)理一遍源碼:
直接進(jìn)入Object.defineProperty的get方法:
考驗(yàn)?zāi)汩]包能力的時(shí)候到了,這個(gè)dep對(duì)象就是一個(gè)閉包。記下來(lái)我們看看dep.depend()方法的實(shí)現(xiàn)。
先暫停一下,上面兩處都用到了 Dep.target ,我也說(shuō)了它就是一個(gè)Watcher實(shí)例化對(duì)象,你是不是很想搞懂它到底在哪里賦值的呢,不急請(qǐng)跟著我下面的代碼看看。
搞懂了Dep.target等于一個(gè)Watche對(duì)象,現(xiàn)在繼續(xù)回到之前的思路看watcher.addDep做了什么。
就這樣依賴收集的流程就走完了,是否感覺(jué)很繞。
總結(jié):依賴收集最終在 watcher.newDeps 中push了閉包中傳過(guò)來(lái)的dep對(duì)象,在dep.subs中push了初始化Vue是簡(jiǎn)歷的Watcher對(duì)象,這個(gè)對(duì)象的,this.getter = expOrFn,傳過(guò)來(lái)的expOrFn是后期數(shù)據(jù)更新頁(yè)面渲染的核心步驟,需要沉下心來(lái)好好去理理。
2、視圖更新流程:
</>復(fù)制代碼
set ->
dep.notify() ->
subs[i].update() ->
watcher.run() || queueWatcher(this) ->
watcher.get() || watcher.cb ->
watcher.getter() ->
vm._update() ->
vm.__patch__()
視圖更新會(huì)經(jīng)過(guò)以上流程,最終調(diào)用Vue的虛擬Dom diff過(guò)程實(shí)時(shí)更新界面視圖
走到此處后面我就不去跟蹤了,后面會(huì)調(diào)用vm.__patch__ 方法,進(jìn)而執(zhí)行虛擬DOM的diff過(guò)程實(shí)時(shí)的更新界面。
總結(jié):
要很好的理解vue的數(shù)據(jù)雙向綁定就要比較耐心,沉下心來(lái)慢慢理解,同時(shí)也需要對(duì)vue的源碼有個(gè)大致的理解,不然你只會(huì)看的越來(lái)越煩躁越來(lái)越?jīng)]有信心。
vue很好的利用了Object.defineProperty方法的 get和set方法,訂閱者發(fā)布者的設(shè)計(jì)思路,巧妙的組織代碼,值得我們很深入的去學(xué)習(xí)和理解,從而促使我們更好的去使用它。謝謝尤大的無(wú)私奉獻(xiàn),讓我們提高了生產(chǎn)力,把更多的精力花到業(yè)務(wù)邏輯中去。
原文地址:https://github.com/wangweiang...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94214.html
摘要:接下來(lái)要看看這個(gè)訂閱者的具體實(shí)現(xiàn)了實(shí)現(xiàn)訂閱者作為和之間通信的橋梁,主要做的事情是在自身實(shí)例化時(shí)往屬性訂閱器里面添加自己自身必須有一個(gè)方法待屬性變動(dòng)通知時(shí),能調(diào)用自身的方法,并觸發(fā)中綁定的回調(diào),則功成身退。 本文能幫你做什么?1、了解vue的雙向數(shù)據(jù)綁定原理以及核心代碼模塊2、緩解好奇心的同時(shí)了解如何實(shí)現(xiàn)雙向綁定為了便于說(shuō)明原理與實(shí)現(xiàn),本文相關(guān)代碼主要摘自vue源碼, 并進(jìn)行了簡(jiǎn)化改造,...
摘要:與狀態(tài)同步非常困難通過(guò)添加觀察者監(jiān)測(cè)變化,如和。應(yīng)用中狀態(tài)的屬性會(huì)被監(jiān)測(cè),當(dāng)它們發(fā)生變化時(shí),只有依賴了發(fā)生變化屬性的元素會(huì)被重新渲染。 現(xiàn)代 js 框架存在的根本原因 然而通常人們(自以為)使用框架是因?yàn)椋核鼈冎С纸M件化;它們有強(qiáng)大的社區(qū)支持;它們有很多(基于框架的)第三方庫(kù)來(lái)解決問(wèn)題;它們有很多(很好的)第三方組件;它們有瀏覽器擴(kuò)展工具來(lái)幫助調(diào)試;它們適合做單頁(yè)應(yīng)用。 Keeping...
摘要:具體步驟實(shí)現(xiàn)將需要的數(shù)據(jù)對(duì)象進(jìn)行遞歸遍歷,包括子屬性對(duì)象的屬性,都加上和。綜上,在性能上的收益并不是最主要的,更重要的是它使得具備了現(xiàn)代框架應(yīng)有的高級(jí)特性。 原文:你應(yīng)該要知道的Vue.js 組件data為什么必須是函數(shù)? 因?yàn)榻M件可能被多處使用,但他們的data是私有的,所以每個(gè)組件都要return一個(gè)新的data對(duì)象 組件通信 父子組件通信:$on、$emit 非父子組件的通信...
摘要:在學(xué)習(xí)過(guò)程中,為加上了中文的注釋,希望可以對(duì)其他想學(xué)習(xí)源碼的小伙伴有所幫助。數(shù)據(jù)綁定原理前面已經(jīng)講過(guò)數(shù)據(jù)綁定的原理了,現(xiàn)在從源碼來(lái)看一下數(shù)據(jù)綁定在中是如何實(shí)現(xiàn)的。 寫在前面 因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。文章的原地址:https://github.com/answershuto/le...
閱讀 2892·2021-09-28 09:36
閱讀 3644·2021-09-27 13:59
閱讀 2496·2021-08-31 09:44
閱讀 2283·2019-08-30 15:54
閱讀 2358·2019-08-30 15:44
閱讀 1190·2019-08-30 13:45
閱讀 1230·2019-08-29 18:38
閱讀 1217·2019-08-29 18:37