王鵬強
摘要:互聯網的不斷發展,前端開發人員一直致力于開發更加高效的代碼,由于前期網速以及前端語言的限制,始終得不到解決,近年來,這些問題得到解決后,越來越多的前端框架誕生,這些框架都趨向于工程化,不斷提高前端開發者的開發效率以及用戶的體驗度。該文就近年來出現的MVVM框架中的Vue做出一些深入的研究,解析MVVM框架的原理及實現。
關鍵詞:MVVM;VUE;前端
中圖分類號:TP311 文獻標識碼:A
文章編號:1009-3044(2019)11-0097-02
Abstract: With the continuous development of the Internet, front-end developers have been devoting themselves to developing more efficient code. Because of the limitations of network speed and front-end language, they have not been solved. In recent years, after these problems have been solved, more and more front-end frameworks have been born. These frameworks tend to be engineering, and constantly improve the development efficiency of front-end developers and user experience. This paper makes some in-depth research on Vue in MVVM framework, which appears in recent years, and analyses the principle and implementation of MVVM framework.
Key words: MVVM; VUE; Front-end
1 背景
從早期的靜態HTML頁面,所有的邏輯運算都由后端進行,到1995年網景推出的JavaScript,逐步在客戶端進行部分的邏輯運算,到1999年XMLHTTPRequest的誕生,瀏覽器異步傳輸、局部刷新的實現,再到jQuery的出現,瀏覽器的開發逐步從后端走向前端,到今天,各種MVVM框架順應時代發展的潮流,引導前端技術走向工程化。
2 MVVM框架的產生
前端的飛速發展,以及互聯網時代的到來,一個大型web網站項目需要成千上萬個HTML界面組成。前后端的未分離,以及JavaScript與HTML的混合使用,對于網站維護人員來說,無從下手,增加了不必要的難度。web開發者一直尋求屬于前端的模塊化框架,2009年,AngularJS的誕生,到2011年React和Ember,再到2014年Vue.js的出現,標志著屬于前端的工程化框架正在取代以往的開發模式。
3 MVVM框架的組成
MVVM,全名Model-View-ViewModel,前端開發者只用關注數據,使用數據的變化改變DOM,也就是視圖的變化,以往的開發模式是開發者在數據改變的時候,手動去操作DOM,這樣的開發模式不僅費時費力,維護時更是難上加難。MVVM通過數據的雙向綁定,當數據發生變化時,局部界面自動重新渲染,解耦View層,也就是視圖層。
3.1 Model
Model層,也就是數據層,用于邏輯處理以及數據的處理。這一層,前端開發者無需關注后端的數據的處理,只需要后端暴露接口,通過后端返回的數據格式,前端開發人員進行相應的數據處理。
3.2 View
視圖層,用于展示用戶界面,不負責數據的處理,用于數據綁定的聲明,指令的聲明,事件綁定的聲明。
3.3 ViewModel
負責Model層與View層的交互,是其中最重要的一環,將Model的數據進行監聽,當數據發生改變時,及時更新視圖。這一層由框架封裝完成,網站開發人員只需關注Model中數據的處理,實現數據驅動視圖。
4 MVVM的優點
1) 低耦合。View層與Model層相互聯系,又可以相互獨立,數據可以雙向綁定又可以單向傳遞。
2) 組件化。模塊化的應用,出現組件的重復利用,同樣的視圖模板,開發人員可以重復利用,提高開發效率,后期更容易維護。
3) 易于開發。由于數據驅動視圖,開發人員更多的重心放在數據的處理與業務邏輯,極大地提高開發效率。
5 實現分析
5.1 發布/訂閱者模式
發布/訂閱者模式是Vue使用的開發模式,通過訂閱者訂閱不同的需求,也就是相應的數據處理,發布者將Dep中訂閱者依次遍歷執行,執行對應的回調函數。
Vue使用Observer監聽new Vue()實例對象,通過Watcher添加對應的訂閱者,Dep收集這些訂閱者,當Data發生改變時,Observer通知Dep,當前數據綁定的Dep收集器中的訂閱者依次執行,實現數據雙向綁定。Compile指令解析器解析HTML模板中的指令,將對應的解析函數添加進Dep中,數據發生改變時,相應的解析函數會更新視圖。
5.2 Observer的實現
Vue支持IE9及以上,Observer數據監聽器使用數據劫持的方式進行數據監聽,通過Object.defineProperty()來重新定義屬性的getter和setter。
Object.defineProperty(data,key,{
get:function(){},
set:function(){}
})
當對應的數據需要相應的對調函數時,在getter中添加對應的訂閱者,getter中不再做其他操作,只用來添加對應的數據依賴。
在setter中,其中做了一部分判斷,當數據未發生改變時,不做任何操作,提高程序的運算效率,當數據發生改變時,通知Dep(訂閱收集器),執行dep.notify(),notify為dep中定義的一個函數,主要用于遍歷Dep中的所有訂閱者,并執行所有訂閱者的回調函數,更新相應的視圖。這個過程是Vue的設計核心,在這里通過數據攔截完成訂閱者的訂閱,發布者在數據改變后,通知所有訂閱者。
5.3 Dep的實現
Dep(訂閱收集器),顧名思義,用于收集對應的訂閱者,它其中主要由subs,addSub,notify以及相應的sub.update組成。
Subs為一個數組,保存所有的訂閱者,當添加訂閱者時,subs.push(sub)依次添加,每個sub(訂閱者)是獨立的,它具有相應的update函數,用于更新視圖和對應的自定義回調函數。addSub方法用于添加sub,當然需要一個調用這些sub的函數方法,notify方法用于遍歷subs,這個方法在數據的setter方法中執行,保證只有數據發生改變,才去通知所有的訂閱者。
5.4 Watcher的實現
Dep中已經實現添加訂閱者,具體的每個訂閱者的實現由Watcher實現。在Observer的getter方法中,執行相應的添加方法,但是如何觸發getter方法,保證訂閱者只添加一次,Vue在Watcher中做了詳細的操作。
function Watcher(vm, exp, cb) {
this.cb = cb;
this.vm = vm;
this.exp = exp;
this.value = this.get(); // 將自己添加到訂閱器的操作
}
Watcher.prototype={
update:function(){},
run:function(){},
get:function(){}
}
通過new Watcher(),首先緩存自己,保證在Observer的getter方法執行時,將自己添加到Dep中,當添加完成之后,釋放自己,當前屬性再次獲取時,不會二次添加進Dep中。由于傳入到Observer的是當前new Watcher()實例,在Dep收集器中的每個sub(訂閱者)都是一個new Watcher()實例對象,每個實例定義它的回調函數update,在update中執行當前訂閱者的需求。到這一步,基本實現了數據攔截,數據改變驅動訂閱者方法的執行。
5.5 Compile的實現
Compile(指令解析器),以上已經實現了雙向綁定,但是整個過程并沒有去改變DOM,只是實現了數據的雙向綁定,界面并沒有發生實際的改變。所以需要一個Compile來解析和綁定DOM。
首先需要獲取當前的DOM對象,由于操作DOM過于頻繁會影響瀏覽器的渲染速度,在Vue出現了虛擬DOM,它主要是將對應的DOM對象轉為js對象,首先去改變js對象,當js對象發生改變時,再去操作DOM改變。
接下來需要遍歷虛擬DOM中的各個節點,這里我們只負責研究它的雙向綁定,對其中的{{}}進行解析,對其中的數據進行new Watcher()操作,并給Watcher更新視圖的回調函數。這樣,數據的雙向綁定就完成了,當界面的input內容發生改變時,js數據也發生改變,同理,數據發生改變時,界面也同時發生渲染。
6 結束語
前端的發展已經是趨勢,MVVM框架已經占據了大部分市場,前端開發者不再去寫重復的HTML元素,不用一遍又一遍獲取DOM,操作DOM,既提高了開發效率,又提高了用戶的使用體驗。SPA(單頁面)應用越來越多,HTML5的跨終端性,讓現在MVVM框架走向移動開發,資源只需加載一次,不僅僅是PC,它在逐漸替代傳統的APP,未來的前端越來越趨向于大前端。
參考文獻:
[1] 孫連山, 李云倩. MVVM框架在Web前端的應用研究[D]. 上海: 復旦大學, 2014.
[2] 劉立. MVVM 模式分析與應用[J]. 微型電腦應用, 2012, 28(12): 57-60.
[3] 何煥春, 楊懌. 基于MVVM構架的Web前端框架研究[J]. 電腦知識與技術, 2017, 13(24):59-60.
[4] 莫文水. Web前端中MVVM框架的應用研究[J]. 網絡安全技術與應用, 2017(4): 64.
[5] 易劍波. 基于MVVM模式的WEB前端框架的研究[J]. 信息與電腦: 理論版, 2016(19): 76-77, 84.
【通聯編輯:謝媛媛】