把自己对这MVVM设计模式的理解整理并记录,仅作自己以后查询之用。

先说前端为什么需要 MVVM 或者 FLUX。在我看来,是为了保证不那么优秀的前端er在团队中写出不那么垃圾的代码,即使确实十分垃圾,也不会污染到团队中其他同事的代码,其它的设计模式应该也具有这种作用。

通过代码对比理解MVVM

MVVM 是 Model-View-ViewModel (双向数据绑定)的简写。不管是 MVVM 或者是 FLUX, 都强调的是视图和数据的分离。MVVM 是将视图和数据分离之后,通过 ViewModel 将数据和视图进行绑定。

View 一般是指模板,例如 Handlerbars ,或者 ES6 的字符串模板,写法如下:

let message = 'hello,world!!'
let demo = `
<div id="demo">
    <p>${message}</p>
</div>
`

然后通过 jQuery 插入 body 中

  $('body').html(demo)

对于 demo 便是 View,message 是此 View 指定的 Model。由于在这个例子中并没有交互,仅仅只是为了说明视图和模型, 所以并没有 VM 部分。

下面的例子是一个完整的用 JQuery 实现的 MVVM 模式写法

//------ Model
let model = {
  value: 1,
  fns: [],
  set: function(v) {
    this.value = v
    this.fns.forEach(fn => fn.call(this, this.value))
  },
  on: function(fn) {
    this.fns.push(fn)
  }
};


//------ View
let demo = `
<div>
<p>${model.value}</p>
<input value='${model.value}' />
<button id="button1">+1</button>
</div>
`

$('body').html(demo)

//------ ViewModel

$('input').on('keyup', function() {
    model.set($(this).val()|0)
})


$('button#button1').on('click', function() {
    model.set(model.value + 1)
})


model.on(function(value) {
  $('p').html(value)
  $('input').val(value)
})

在这个例子中, input输入的内容会实时显示在p标签中,而button被点击之后,也会对p标签的值和input标签的值都做+1处理;如果我们按照通常的 jQuery 来处理的话应该怎么做?

$('input').on('keyup', function() {
  let value = $(this).val()|0;
  $('p').html(value)
  $('input').val(value)
})

$('button').on('click', function() {
    let value = $('input').val()|0 + 1;
    $('p').html(value)
    $('input').val(value)
})

从这两段代码来看,并没有太大区别,甚至下面一段代码看起来更短。然而下面一段代码将 视图和模型的处理写到了一起,试想一下,当我们想再增加一个 -1 的button 呢?对于 MVVM的模式,只要再写

<button id='button2'>-1</button>
$('button#button2').on('click', function() {
    model.set(model.value - 1)
})

即可。

而对于传统的方式,还需要先取得当前input值或p的值,然后再进行-1操作,最后还需要将input和p的innerHTML都修改一次。
随着DOM的增加,处理难度的差距越来越大,越来越不容易理解,修改一次,如履薄冰。

通过这个小例子可以看出 MVVM 相对传统的写法的最大的优势:

  1. 视图和模型的分离,视图可以独立模型进行开发;只需约定模型的结构即可。

  2. 双向数据绑定,视图和模型可以通过VM互相改变。

  3. 基于约定俗成的模式,可以将烂代码控制在最小范围内,也很难写出烂代码。

ps: 按照我的理解 Angular 中对于基础的VM进行了封装,所以在模板中绑定数据之后,数据更新,会自动更新视图。


zwhu
1.8k 声望61 粉丝