- Vue.js前端開發基礎與項目實戰
- 鄭韓京
- 2396字
- 2020-04-28 10:35:48
1.2 MVC、MVP、MVVM傻傻分不清楚
在開始講解本節內容之前,先舉一個例子,如圖1.2所示。

圖1.2 MV系列框架例子
這是一個很簡單的計數器,單擊“減”按鈕,數字就會減1;單擊“加”按鈕,數字就會加1。
接下來需要知道的是,在MV系列框架中,M和V指Model層和View層,但是其功能會因為框架的不同而變化。Model層很好理解,就是存儲數據;View層則是展示數據,讀者能看見這個例子,完全就是因為存在View層。雖然在不同的框架中,View層和Model層的內容可能會有所差別,但是其基礎功能不變,變的只是數據的傳輸方式。
下面就從這個例子開始了解MV系列框架的概念。
1.2.1 MVC小解
MVC框架是MVC、MVP、MVVM這3個框架中歷史最悠久的。20世紀70年代,施樂公司發明了Smalltalk語言,用來編寫圖形界面的應用程序,脫離了DOS系統,讓系統可視化,不用一直看著黑白的界面。
在Smalltalk發展到80版本的時候,MVC框架被一位工程師提出來,MVC框架的出現在很大程度上降低了應用程序的管理難度,之后被廣泛應用于構架桌面和服務器應用程序。MVC框架如圖1.3所示(實線表示調用,虛線表示通知)。

圖1.3 MVC框架圖
Controller是MVC中的C,指控制層,在Controller層會接收用戶所有的操作,并根據寫好的代碼進行相應的操作——觸發Model層,或者觸發View層,抑或是兩者都觸發。需要注意:Controller層觸發View層時,并不會更新View層中的數據,View層中的數據是通過監聽Model層數據變化而自動更新的,與Controller層無關。MVC框架流程如圖1.4所示。

圖1.4 MVC框架流程圖
從圖1.4中可以看出,MVC框架的大部分邏輯都集中在Controller層,代碼量也都集中在Controller層,這帶給Controller層很大的壓力,而已經有獨立處理事件能力的View層卻沒有用到。還有一個問題,就是Controller層和View層之間是一一對應的,斷絕了View層復用的可能,因而產生了很多冗余代碼。為了解決這個問題,MVP框架被提出來。
1.2.2 MVP小解
首先需要知道,MVP不是指Most Valuable Player,而是指Model-View-Presenter。
MVP框架比MVC框架大概晚出現20年,1990年,MVP由IBM的子公司Taligent公司提出,它最開始好像是一個用于C++ CommonPoint的框架,這種說法正確與否這里不做考證,先來看一下MVP框架圖(圖1.5)。

圖1.5 MVP框架圖
在MVC框架中,View層可以通過訪問Model層來更新,但在MVP框架中,View層不能再直接訪問Model層,必須通過Presenter層提供的接口,然后Presenter層再去訪問Model層。這看起來有點多此一舉,但用處著實不小。首先是因為Model層和View層都必須通過Presenter層來傳遞信息,所以完全分離了View層和Model層,也就是說,View層與Model層一點關系也沒有,雙方是不知道彼此存在的,在它們眼里,只有Presenter層。其次,因為View層與Model層沒有關系,所以View層可以抽離出來做成組件,在復用性上比MVC模型好很多。MVP框架流程如圖1.6所示。

圖1.6 MVP框架流程圖
從圖1.6中可以看出,View層與Model層確實互不干涉,View層也自由了很多。但還是有問題,因為View層和Model層都需經過Presenter層,致使Presenter層比較復雜,維護起來會有一定的問題。而且因為沒有綁定數據,所有數據都需要Presenter層進行“手動同步”,代碼量比較大,雖然比MVC模型好很多,但也是有比較多的冗余部分。為了讓View層和Model的數據始終保持一致,避免同步,MVVM框架出現了。
1.2.3 MVVM小解
MVVM最早是由微軟在使用Windows Presentation Foundation和SilverLight時定義的,2005年微軟正式宣布MVVM的存在。VM是ViewModel層,ViewModel層把Model層和View層的數據同步自動化了,解決了MVP框架中數據同步比較麻煩的問題,不僅減輕了ViewModel層的壓力,同時使得數據處理更加方便——只需告訴View層展示的數據是Model層中的哪一部分即可,MVVM框架如圖1.7所示。

圖1.7 MVVM框架圖
讀者可能感覺MVVM的框架圖與MVP的框架圖相似,確實如此,兩者都是從View層開始觸發用戶的操作,之后經過第三層,最后到達Model層。但是關鍵問題是這第三層的內容,ViewModel層雙向綁定了View層和Model層,因此,隨著View層的數據變化,系統會自動修改Model層的數據,反之同理。而Presenter層是采用手動寫方法來調用或者修改View層和Model層,兩者孰優孰劣不言而喻。MVVM框架流程圖如圖1.8所示。

圖1.8 MVVM框架流程圖
從圖1.9可以看出,View層和Model層之間數據的傳遞也經過了ViewModel層,ViewModel層并沒有對其進行“手動綁定”,不僅使速度有了一定的提高,代碼量也減少很多,相比于MVC和MVP,MVVM有了長足的進步。

圖1.9 數據綁定概念
至于雙向數據綁定,可以這樣理解:雙向數據綁定是一個模板引擎,它會根據數據的變化實時渲染。這種說法可能不是很恰當,但是很好理解,如圖1.9所示。
如圖1.9所示,View層和Model層之間的修改都會同步到對方。MVVM模型中數據綁定方法一般有以下3種。
數據劫持
發布-訂閱模式
臟值檢查
Vue..js使用的是數據劫持和發布-訂閱模式兩種方法。首先來了解3個概念。
Observer:數據監聽器
Compiler:指定解析器
Watcher:訂閱者
Observer用于監聽數據變化,如果數據發生改變,不論是在View層還是Model層,Oberver都會知道,然后告訴Watcher。Compiler的作用是對數據進行解析,之后綁定指定的事件,在這里主要用于更新視圖。
Vue.js數據綁定的流程:首先將需要綁定的數據用數據劫持方法找出來,之后用Observer監聽這堆數據,如果數據發生變化,Observer就會告訴Watcher,然后Watcher會決定讓哪個Compiler去做出相應的操作,這樣就完成了數據的雙向綁定。
1.2.4 三者的區別和優劣
詳細了解MV系列框架之后,相信讀者已經了解MVC、MVP、MVVM這三者的優劣了。其實從MVC到MVP再到MVVM,是一個不斷進步的過程,后兩者都是在MVC的基礎上做的變化,使MVC更進一步,使用起來也更加方便。MVC、MVP、MVVM三者的主要區別就在于除View層和Model層之外的第三層,這一層的不同使得MV系列框架區分開來。
其實很難說出MVC、MVP、MVVM哪一個更好,從表面上看,顯然是MVVM最好,使用起來更方便,代碼相對也較少。但問題是MVVM的框架體積較大,相比于MVC的不用框架、MVP的4KB框架,MVVM遙遙領先。雖然MVVM框架可以單獨引用,但現在更多使用前端腳手架工具進行開發,并且使用打包工具,這樣一來,它跟MVC相比,體積是天差地別。雖然機能過剩更令人放心,但是輕巧一些的框架會令項目錦上添花。所以要根據實際項目的需求來選擇MVC、MVP、MVVM,只有最適合的模式才是最好的框架。
每項新技術都要經歷一個從一開始不被大眾認可到后來人盡皆知的過程,其實就是一個改變的過程。只要這個框架能跟上時代的潮流,滿足人們開發的需求,這就是一個合適的框架。
因此,如果你想真正從事開發這一行業(尤其是前端),需要擁有一顆不懼變化的心。