官术网_书友最值得收藏!

3.2 前端開發模式

3.2.1 抽象DOM模式

AJAX技術為前端提供了局部刷新技術,使業界更加注重用戶的交互,因此出現了各種對DOM進行操作的JS框架。相比JavaScript原生API,這些框架提供了豐富的DOM選擇器,封裝了更加方便的DOM操作和AJAX交互操作接口,屏蔽了各種瀏覽器的差異。典型代表如jQuery。DOM交互框架使JS的編寫變得簡單,生產力得到了極大的提高。

早期的JS框架以滿足PC端需求為主要工作目標,移動互聯網快速發展,前端需要適應各種屏幕分辨率、滿足各種手勢操作的需求,對前端的要求越來越高。早期JS框架主要解決了DOM交互的問題,當前端功能較多時,從后端獲取的數據和HTML展示與用戶操作相關的代碼混合在一起,層次不清,較難開發和維護。

3.2.2 MVC模式

參照后端的主流架構模式,在前端也出現了MVC模式,即前端分為數據層(Model)、視圖層(View)、控制器層(Controller)。圖3-1表示了前端MVC模式與服務端的關系。從前端到服務端的整個架構看,主要的業務處理邏輯依然在服務端處理,前端主要負責展示。前端的MVC架構是對服務端View層次在瀏覽器或客戶端上的處理邏輯的進一步細化。

圖3-1 前端MVC模式與服務端

在前端自有的MVC架構中,View層包括了頁面展示和事件處理,Model層主要負責前端數據處理,包括數據格式處理、與服務端的網絡通信等。而Controller主要負責View與Model的耦合,處理業務邏輯。

3.2.3 MVP模式

在前端的MVC模式中,View層功能內容較多,可以直接與Model層交互。如對輸入框復制等功能是可以直接調用Model層數據的。

在MVP模式中,使用Presenter替代了Controller。MVP與MVC的本質區別是:在MVP中,View并不直接使用Model,它們之間的通信是通過Presenter(對應MVC中的Controller)來進行的,所有的交互都發生在Presenter內部,而在MVC中View會直接從Model中讀取數據而不是通過Controller。前端MVC模式是一個相互連接的三角形結構,而MVP模式是一個上下垂直的層次結構。前端的MVP模式的層次關系與服務端的MVC模式更加相似。MVP模式剝離了視圖與狀態的關系,使視圖從特定的業務場景中抽離。MVC模式與MVP模式的區別如圖3-2所示。

圖3-2 前端MVC與MVP模式

3.2.4 MVVM模式

MVVM模式(Model-View-ViewModel)是MVP模式的進一步改進,其中的Model和View與MVP模式一致,ViewModel是一個同步View和Model的對象。

MVVM的核心思想是數據雙向綁定(data-binding),View和Model之間通過ViewModel進行交互,沒有聯系。交互是雙向的,View數據的變化會同步到Model中,而Model數據的變化也會反映到View上。交互還是自動的,無需人為干涉,View與Model之間的雙向狀態維護由ViewModel來統一管理。

圖3-3清晰地表達了MVVM模式的結構。從View側看,ViewModel中的DOM Listeners工具會監測頁面上DOM元素的變化,并將變化傳遞給Model,同步更改Model數據;從Model側看,當更新Model中的數據時,Data Bindings工具會更新頁面中的DOM元素。

圖3-3 Vue的MVVM模式

相比MVC或MVP模式,MVVM要實現自動雙向綁定對框架要求更高,封裝更深。MVVM框架通過HTML自定義屬性與Model建立對應關系,如<input epub:type="text"v-model="message">與model中的“message”變量相對應。通過劫持Model數據的get和set方法,當Model發生變更時Data Bindings工具會掃描DOM樹中與Model相對應的元素,更新元素的innerHTML。反之,DOM Listeners會監聽HTML元素的change、keyup、select等事件,通過事件觸發改變HTML元素對應的Model數據。

前端主流JS框架中VUE與AngularJS都實現了MVVM模式。

在MVVM模式下,頁面的變化由數據驅動,反之用戶操作又會驅動數據變化,框架自動管理交互操作,解放了大量的內容渲染和事件綁定的DOM操作邏輯,使開發人員更加關注業務邏輯。

對比Web應用、App原生應用以及后端應用的MV*架構,會發現它們在實現中有很多差異。前端應用中主要是處理用戶交互,所以前端架構中Vi e w層較重。同時編程語言不同,功能分工也有所差異,如Android原生開發的View層含有很多事件處理程序,類似于Spring MVC的Controller層,而JS頁面的MVC功能分工與后端更加相似。從MVC到MVVM,更多的是掌握一種理念和思路,在前端架構中很難完全滿足View層不直接訪問Model層的要求。

3.2.5 Virtual DOM

Virtual DOM是一種用自定義的JavaScript對象代替DOM樹的結構。

使用Virtual DOM更新頁面時,首先用Virtual DOM樹構建一個真正的DOM結構。當DOM文檔狀態變化時,會新建一棵Virtual DOM樹,并將新樹與舊樹進行對比,記錄兩棵樹的差異。最后將對比后的差異修改到真實的DOM樹上。Virtual DOM本質是用戶JS與DOM之間的緩沖,采用了DocumentFragment的機制,Virtual DOM記錄下多次DOM操作,一次提交,避免多次渲染。基于Virtual DOM的頁面更新過程如圖3-4所示。

圖3-4 基于Virtual Dom的頁面更新

真正的DOM對象有非常龐大的結構,而自定義的JavaScript對象較為簡單,只需要具有節點類型tag、屬性attributes和子節點children就可以。每次真正的DOM操作都會導致瀏覽器進行頁面渲染,這是一個非常繁重的工作。DocumentFragment對象是標準語法,與document級別相同。JS構造DocumentFragment時不影響Document,不會進行頁面渲染。當DocumentFragment節點全部構造完成后,再將DocumentFragment對象添加到Document中,所有的節點都會一次性渲染出來,避免了逐個修改Document導致的瀏覽器反復渲染,減少瀏覽器負擔,提高頁面渲染速度。

分析記錄兩棵DOM樹差異的過程也叫DOM Dif,是Virtual DOM的核心。大量基于Virtual DOM的應用證實了DOM Dif算法是高效的。React與Vue框架都以Virtual DOM為核心,提高頁面渲染效率。Virtual DOM將用戶操作與頁面渲染隔離,有利于構建跨端的應用,ReactNative和Weex就是采用這種模式。

3.2.6 組件化編程

在CS架構流行時,Delphi以強勁的組件開發能力受到追捧。Delphi等工具提供了豐富的組件,極大地簡化了開發工作,推動CS模式的開發達到了頂峰。

組件化可以將一個龐大且復雜的UI場景分解成幾個小的部分,這些小的部分彼此之間互不干擾,單獨開發,單獨維護,任意組合。組件化將復雜的邏輯封裝在內部,大幅度地提高了代碼的復用性,開發者們不需要再面對復雜且難懂的代碼,只需要關注組件的組合和使用,同時也降低了維護成本。

Web前端的組件化最開始還是從服務端做起。為了適應服務端的MVC框架,在JSP上使用了Struts標簽等服務端模板,模板經框架解析后在瀏覽器上展示出HTML。AJAX流行后,各種DOM操作框架百花齊放,很多框架將HTML、CSS和DOM操作封裝,出現了真正的前端框架,典型如easyUI、DOJO等框架。移動互聯網時代,無論是App原生應用還是Web開發都將組件化編程作為重要手段。Web開發中,React、AngularJS、Vue等主流框架都以組件化作為前端開發的核心,大量第三方機構也封裝了靈活、美觀的第三方組件,如:AntDesign、ElementUI等。新一代的UI組件以MVVM、Virtual DOM、預編譯的CSS、擴展HTML元素、DOM操作為基礎。

組件(Component)是Vue.js最強大的功能之一。圖3-5是Vue官網的組件化相關說明圖。

圖3-5 Vue中的頁面組件

在Vue中,可以通過嵌套的組件樹構造應用,如定制頁頭、側邊欄、內容區等父組件,父組件中可以包含導航鏈接、博文內容之類的子組件。通過前端的組件技術,可以使用獨立可復用的小組件來構建各種大型應用。

圖3-6是一個基于組件的前端架構。組件架構的主要技術這里不再一一介紹,在主流前端框架中對這些技術進行了封裝,提供了組件編程的基礎技術體系。在基礎組件這一層,有非常多的第三方開源產品,如ElementUI就是一套第三方開發的基于Vue的UI組件庫,形成了布局、表單、導航、對話框等常用的基礎UI組件。通過對基礎UI組件的封裝,可以形成業務組件,如登錄、支付、分享、點贊、評論、搜索等。通過這些業務組件再組裝成應用界面,幾乎任意類型的應用的界面都可以抽象為這樣一個組件樹。

圖3-6 基于組件的前端架構

主站蜘蛛池模板: 深水埗区| 赫章县| 安龙县| 双桥区| 中西区| 奉贤区| 图木舒克市| 荣昌县| 垦利县| 广元市| 安西县| 五河县| 保靖县| 饶平县| 鲜城| 十堰市| 淳安县| 嘉定区| 大荔县| 海盐县| 法库县| 安塞县| 青冈县| 天气| 沙坪坝区| 昆山市| 东兰县| 十堰市| 子长县| 永新县| 家居| 灵寿县| 延吉市| 凯里市| 瓮安县| 和静县| 惠安县| 民权县| 钟祥市| 塘沽区| 轮台县|