- Published on
打造属于自己的MVVM框架: 1.什么是MVVM
- Authors
- Name
- Pursue
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 中的模版引擎和数据绑定(单项,双向)。