Published on

打造属于自己的MVVM框架: 1.什么是MVVM

Authors
  • avatar
    Name
    Pursue
    Twitter

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 中的模版引擎和数据绑定(单项,双向)。