利用 ES6 的字符串模板和 JQuery 简单理解 MVVM

孙仲
• 阅读 5243

把自己对这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进行了封装,所以在模板中绑定数据之后,数据更新,会自动更新视图。

点赞
收藏
评论区
推荐文章
责任链和策略设计模式-基于Java编程语言
责任链和策略设计模式这两种设计模式非常实用,下面简单介绍一下我对这两种设计模式的理解和它们在Spring框架源码中的应用。
徐小夕 徐小夕
4年前
《前端实战总结》之迭代器模式的N+1种应用场景
眼看12月就来了,抓住今年的尾巴,好好总结一下前端的不足与收获。这篇文章是笔者写设计模式专题的第二篇文章,也是基于工作中的总结和提炼,在实际应用场景中都会大量使用,至于为什么要写设计模式,主要是为了提高团队代码质量和可维护性,后续会继续推出设计模式相关的文章,供大家参考和学习。你将学到迭代器模式的含义实现一个数组迭代器实现一个对象迭代器
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java24种设计模式
一、设计模式定义  设计模式(DesignPattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。二、设计模式分类  经典模式只有23个(还有简单工厂模式),它们各具特色,每个模式都为某一个可重复的设计问题提供了一套解决方案。  根据它们的用
Stella981 Stella981
3年前
JS中!function(){}()的理解
这种写法,是一种立即执行函数的写法,即IIFE等设计模式。这种函数在函数定义的地方就直接执行了。理解IIFE设计模式的关键是要认识到,在ES6之前,JavaScript仅具有函数作用域(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fen.wikipedia.org%2Fwiki
Wesley13 Wesley13
3年前
Java 设计模式(1)
设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种
Wesley13 Wesley13
3年前
2.7万 Star!最全面的 Python 设计模式集合
【导语】:设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易地被他人理解、保证代码可靠性。pythonpatterns则是使用python实现设计模式的集合。简介学会了很多门编程语言,就是一个好程序员了吗?事实上,入门很简单,但真正的精通不仅需要会写出简单的类似“
Stella981 Stella981
3年前
React 世界的一等公民
Choerodon猪齿鱼平台使用React作为前端应用框架,对前端的展示做了一定的封装和处理,并配套提供了前端组件库ChoerodonUI。结合实际业务情况,不断对组件优化设计,提高代码质量。本文将结合Choerodon猪齿鱼平台使用案例,简单说明组件的分类、设计原则和设计模式,帮助开发者在不同场景下选择正确的设计和方案编写组件(示例代码基于ES6
Wesley13 Wesley13
3年前
Java开发中的23种设计模式详解(转)
设计模式(DesignPatterns)                                 ——可复用面向对象软件的基础设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他
一文带你读懂设计模式之责任链模式 | 京东云技术团队
翻了一下之前刚入职时候的学习笔记,发现之前在熟悉业务代码的时候曾经专门学习并整理过过设计模式中的责任链模式,之前只是对其简单了解过常用的设计模式有哪些,并未结合实例和源码深入对其探究,利用熟悉代码契机进行系统学习并整理文档如下。