MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。
把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。需要用JavaScript编写一个通用的ViewModel,这样,就可以复用整个MVVM模型了。
单向绑定
MVVM就是在前端页面上,应用了扩展的MVC模式,我们关心Model的变化,MVVM框架自动把Model的变化映射到DOM结构上,这样,用户看到的页面内容就会随着Model的变化而更新。
经过MVVM框架的自动转换,浏览器就可以直接显示Model的数据。目前,常用的MVVM框架有:
1 | Angular:Google出品,名气大,但是很难用; |
我们选择MVVM的目标应该是入门容易,安装简单,能直接在页面写JavaScript,需要更复杂的功能时又能扩展支持。综合考察,最佳选择是尤雨溪大神开发的MVVM框架:Vue.js 目前,Vue.js的最新版本是2.0,我们会使用2.0版本作为示例。
创建基于koa的Node.js项目结构如下:
编写MVVM
Model是一个JavaScript对象,它包含两个属性:
1 | { |
而负责显示的是DOM节点可以用和来引用Model的属性:
1 | <div id="vm"> |
最后一步是用Vue把两者关联起来。
在
内部编写的JavaScript代码,需要用jQuery把MVVM的初始化代码推迟到页面加载完毕后执行,否则,直接在内执行MVVM代码时,DOM节点尚未被浏览器加载,初始化将失败。正确的写法如下:1 | <html> |
其中,el指定了要把Model绑定到哪个DOM根节点上,语法和jQuery类似。这里的’#vm’对应ID为vm的一个
在该节点以及该节点内部,就是Vue可以操作的View。Vue可以自动把Model的状态映射到View上,但是不能操作View范围之外的其他DOM节点。
然后,data属性指定了Model,我们初始化了Model的两个属性name和age,在View内部的
节点上,可以直接用引用Model的某个属性。
如果打开浏览器console,因为我们用代码window.vm = vm,把VM变量绑定到了window对象上,所以,可以直接修改VM的Model:
Vue作为MVVM框架会自动监听Model的任何变化,在Model数据变化时,更新View的显示。这种Model到View的绑定我们称为单向绑定。
单向绑定
在Vue中,可以直接写绑定某个属性。如果属性关联的是对象,还可以用多个.引用,例如,。
另一种单向绑定的方法是使用Vue的指令v-text,写法如下:
Hello, !
这种写法是把指令写在HTML节点的属性上,它会被Vue解析,该节点的文本内容会被绑定为Model的指定属性,注意不能再写双花括号{{ }}。
双向绑定
在Vue中,使用双向绑定非常容易,我们仍然先创建一个VM实例:
1 | $(function () { |
然后,编写一个HTML FORM表单,并用v-model指令把某个<input>和Model的某个属性作双向绑定:
1 | <form id="vm" action="#"> |
我们可以在表单中输入内容,然后在浏览器console中用window.vm.$data查看Model的内容,也可以用window.vm.name查看Model的name属性,它的值和FORM表单对应的<input>是一致的。
如果在浏览器console中用JavaScript更新Model,例如,执行window.vm.name=’22222’,表单对应的<input>内容就会立刻更新。
多个checkbox可以和数组绑定:
1 | <label><input type="checkbox" v-model="language" value="zh"> Chinese</label> |
对应的Model为:
1 | language: ['zh', 'en'] |
单个checkbox可以和boolean类型变量绑定:
<input type="checkbox" v-model="subscribe">
对应的Model为:
subscribe: true; // 根据checkbox是否选中为true/false
下拉框<select>绑定的是字符串,但是要注意,绑定的是value而非用户看到的文本:
1 | <select v-model="city"> |
对应的Model为:
city: ‘bj’ // 对应option的value
双向绑定最大的好处是我们不再需要用jQuery去查询表单的状态,而是直接获得了用JavaScript对象表示的Model。
处理事件
当用户提交表单时,传统的做法是响应onsubmit事件,用jQuery获取表单内容,检查输入是否有效,最后提交表单,或者用AJAX提交表单。
现在,获取表单内容已经不需要了,因为双向绑定直接让我们获得了表单内容,并且获得了合适的数据类型。
响应onsubmit事件也可以放到VM中。我们在