Vue.js 最顯著的功能就是響應(yīng)式系統(tǒng),它是一個(gè)典型的 MVVM 框架,模型(Model)只是普通的 JavaScript 對(duì)象,修改它則視圖(View)會(huì)自動(dòng)更新。這種設(shè)計(jì)讓狀態(tài)管理變得非常簡(jiǎn)單而直觀
Vue的MVVM模型示意圖
Vue數(shù)據(jù)響應(yīng)原理圖
實(shí)現(xiàn)MVVM通用方式
要實(shí)現(xiàn)mvvm的雙向綁定,就必須要實(shí)現(xiàn)以下幾點(diǎn):
1、實(shí)現(xiàn)一個(gè)數(shù)據(jù)監(jiān)聽器Observer,能夠?qū)?shù)據(jù)對(duì)象的所有屬性進(jìn)行監(jiān)聽,如有變動(dòng)可拿到最新值并通知訂閱者
2、實(shí)現(xiàn)一個(gè)指令解析器Compile,對(duì)每個(gè)元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù),以及綁定相應(yīng)的更新函數(shù)
3、實(shí)現(xiàn)一個(gè)Watcher,作為連接Observer和Compile的橋梁,能夠訂閱并收到每個(gè)屬性變動(dòng)的通知,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù),從而更新視圖
4、mvvm入口函數(shù),整合以上三者
整體感知virtual DOM
virtual DOM分為三個(gè)步驟:
1.createElement(): 用 JavaScript對(duì)象(虛擬樹) 描述 真實(shí)DOM對(duì)象(真實(shí)樹)
2.diff(oldNode, newNode) : 對(duì)比新舊兩個(gè)虛擬樹的區(qū)別,收集差異
3.patch() : 將差異應(yīng)用到真實(shí)DOM樹
有的時(shí)候 第二步 可能與 第三步 合并成一步(Vue 中的patch就是這樣)
Vue的實(shí)現(xiàn)原理總結(jié)
- 首先,在實(shí)例化的過程中,把一個(gè)普通 JavaScript 對(duì)象傳給 Vue 實(shí)例的 data
選項(xiàng),Vue 將遍歷此對(duì)象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter。 - Dep 是一個(gè)依賴收集器。data 下的每一個(gè)屬性都有一個(gè)唯一的 Dep 對(duì)象,在 get 中收集僅針對(duì)該屬性的依賴,然后在 set 方法中觸發(fā)所有收集的依賴。
- 在Watcher中對(duì)表達(dá)式求值,從而觸發(fā)數(shù)據(jù)的get。在求值之前將當(dāng)前Watch實(shí)例設(shè)置到全局,使用pushTarget(this)方法。
- 在get()中收集依賴,this.subs.push(sub),set的時(shí)候觸發(fā)回調(diào)Dep.notify()。
- Compile中首先將template或el編譯成render函數(shù),render函數(shù)返回一個(gè)虛擬DOM對(duì)象(將模板轉(zhuǎn)為 render 函數(shù)的時(shí)候,實(shí)際是先生成的抽象語(yǔ)法樹(AST),再將抽象語(yǔ)法樹轉(zhuǎn)成的 render 函數(shù))
- 當(dāng) vm._render 執(zhí)行的時(shí)候,所依賴的變量就會(huì)被求值,并被收集為依賴。按照Vue中 watcher.js 的邏輯,當(dāng)依賴的變量有變化時(shí)不僅僅回調(diào)函數(shù)被執(zhí)行,實(shí)際上還要重新求值,即還要執(zhí)行一遍
- 如果還沒有 prevVnode 說(shuō)明是首次渲染,直接創(chuàng)建真實(shí)DOM。如果已經(jīng)有了 prevVnode 說(shuō)明不是首次渲染,那么就采用 patch 算法進(jìn)行必要的DOM操作。這就是Vue更新DOM的邏輯。
() => {
vm._update(vm._render(), hydrating)
}
這實(shí)際上就做到了 re-render,因?yàn)?vm._update 就是開頭所說(shuō)的虛擬DOM中的最后一步:patch
詳細(xì)表述
圖片來(lái)源: Vue2.1.7源碼學(xué)習(xí)__HcySunYang
參考資料
Vue2.1.7源碼學(xué)習(xí)
Vue 源碼解析:深入響應(yīng)式原理
重復(fù)造輪子:從0開始實(shí)現(xiàn)Vue數(shù)據(jù)綁定