MVVM(Model View ViewModel)是一種基于MVC的設計,開發人員在HTML上寫一些Bindings,利用一些指令綁定,就能在Model和ViewModel保持不變的情況下,很方便的將UI設計與業務邏輯分離,從而大大的減少繁瑣的DOM操作。
起源
MVVM這個概念最是在2005年,由微軟的工程師John Grossman在其博客中提出,最初這個概念是用在微軟的WPF上的。直到最近幾年,MVVM這種設計才被Javascript所實現,并產生了許多框架,如 KnockoutJS, Kendo MVVM 和 Knockback.js,而這些框架的社區都非常的活躍。
什么是MVVM
-
Model
作為MV*家族中的一員,MVVM中的M代表著Model。Model代表我們整個webapp所需要的數據模型,一個典型的例子就是用戶信息Model,它應該含有(姓名,年齡等屬性)。Model含有大量信息,但它并不具有任何行為邏輯,它只是數據,因而它不會影響瀏覽器如何展示數據。
-
View
View這個詞出現頻率最多的地方應該是MVC。在MVC設計中,View是唯一與用戶交互的地方,或者說它是Model變化后的直觀反映。在MVVM中,View被認為是主動的而非被動的。一個被動的View時只它只能任由“他人”(Controller)擺布,自己卻不能改變任何東西,如利用Jquery操作DOM。而MVVM中View是具有主動性的,因為它包括了一些數據綁定,事件,和行為,這些都會直接影響Model和ViewModel的。它不但負責保持View自己身的行為(展示),而還會將自身的變化同步到ViewModel中。
-
ViewModel
ViewModel可以被看作是MVC中的Controller,它主要負責數轉換(用一定的業務邏輯),它負責將Model的變化反應到View上,而當View自身有變化時也會同步Model進行改變。你可以把ViewModel看作一個藏在View后面的好幫手,它把View需要的數據暴露給它,并且富于View一定的行為能力。說了這么多,先看一個knockoutjs的Demo:
html
<!-- This is a *view* - HTML markup that defines the appearance of your UI -->
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
javascript
// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
this.firstName = "Bert";
this.lastName = "Bertington";
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
頁面效果:
First name: Bert
Last name: Bertington
ViewModel在View上綁定了text指令,告訴對應的tag可以利用ViewModel中的數據渲染DOM。這只是ViewModel對View的單項綁定,雙向綁定需要observable對象,后續會有解釋。
優點
- 1.UI與邏輯的分離。
- 2.寫unit測試比較方便,畢竟測ViewModel要比測個種Event方便多了。
缺點
- 1.如果你在Bindings里寫了自定義的方法,而這個方法恰好需要調試時可能有些不便。
- 2.對于交互很少的webapp,MVVM略顯沉重
- 3.對于大型webapp,所有邏輯和數據都在ViewModel里,ViewModel會越來越復雜。
其實MVVM的缺點還有很多,但都是一些在特定場景下的特定問題,而它的優點個人覺得就是上面的兩大方面,盡管它也有很多不足和缺陷,但是當你的webapp屬于中小型,并且有很復雜的交互時,如果你還在用類似于Jquery去操作DOM,那我還是勸你趕緊換框架吧。
基于一段時間使用MVVM的經驗,個人覺得在特定場景下它確實很優秀,所以我決心自己嘗試著去研究一下MVVM的實現原理,我將會以knockoutjs為基礎,打造一套和它的接口相同的MVVM框架(部分主要接口),不求做的多優秀,只想動手實現一下,我將會在后續的博客中介紹如果實現MVVM中的模版引擎和數據綁定(單項,雙向)。原文請戳