复杂的软件必须有清晰合理的架构,否则无法开发和维护
一、MVC
什么是MVC
MVC(Model-View-Controller)是最常见的软件架构之一
MVC是模型(Model)、视图(View)和控制器(Controller)的缩写,下面有一幅图 可以表明他们之间的关系

MVC如何工作
MVC的一般交互流程就是:
- 用户操纵 View,触发Controller上的一个事件。
- Controller通过事件让Model通知View进行更新。
接下来通过一些简单的代码演示一个简易的MVC模型,首先是Model层
var myApp = {} // 首先创建这个应用对象
myApp.Model = function () {
// model的实现
var val = 0 // 假设当前模型数据为val 当然实际可能有更多
// 定义一些行为
this.add = function (v) {
val += v
}
this.sub = function (v) {
val -= v
}
this.getVal = function () {
return val
}
// 实现一个观察者模式
var self = this,
views = []
this.register = function (view) {
views.push(view)
}
this.notify = function () {
// 通知View更新
for (var i = 0; i < views.length; i++) {
views[i].render(self)
}
}
}
view层
myApp.View = function (controller) {
var $num = $('#num'), // 假设页面上有这样几个节点
$incBtn = $('#incBtn'),
$decBtn = $('#decBtn')
this.render = function (model) {
$num.innerText = model.getVal()
}
// 给按钮绑定事件
$incBtn.click = controller.increase
$decBtn.click = controller.decrease
}
Controller层
myApp.controller = function () {
var model = null,
view = null
// 初始化函数
this.init = function () {
// 初始化Model和View
model = new myApp.Model()
view = new myApp.View(this)
// 让view在model中注册 这样model就可以通知View进行更新
model.register(view)
mdoel.notify()
}
// 通知Model更新数值并让Model更新View视图
this.increase = function () {
model.add(1)
model.notify()
}
this.decrease = function () {
model.sub(1)
model.notify()
}
}
可以看到这里实现了一个简单的MVC模型 用户可以通过操作View节点事件来通知Controller,Controller通过Model来通知View视图进行Render
MVC的优缺点
优点
- 耦合性低
- 重用性高
- 部署快
- 可维护性高
- 有利于软件工程化管理
缺点
- 没有明确的定义
- 不适合中小型的应用
- 增加系统结构和实现的复杂性
- 试图与控制器建过于紧密的连接
- 视图对模型数据的低效率访问
二、MVVM
什么是MVVM
MVVM = Model-View-ViewModel,与 MVC、MVP 不同的就在于最后一个部件,换成了 ViewModel(VM)

同样,这里也实现一个简单的MVVM模型
// model
var data = {
val: 0
};
// view
<div id="myapp">
<div>
<span>{{ val }}rmb</span>
</div>
<div>
<button v-on:click="sub(1)">-</button>
<button v-on:click="add(1)">+</button>
</div>
</div>
// controller
new Vue({
el: '#myapp',
data: data,
methods: {
add(v) {
if(this.val < 100) {
this.val += v;
}
},
sub(v) {
if(this.val > 0) {
this.val -= v;
}
}
}
});
MVVM的实现原理:
MVVM的实现主要是三个核心点:
- 响应式:vue如何监听data的属性变化
- 模板解析:vue的模板是如何被解析的
- 渲染:vue模板是如何被渲染成HTML的
这其中最主要的为vue如何监听data的属性变化
响应式
对于MVVM来说,data一般是放在一个对象当中,就比如这样:
var obj = {
name: 'xxxx',
age: 25
}
当我们访问或修改obj的属性的时候,比如:
console.log(obj.name) //访问
obj.age = 22 //修改
但是这样的操作vue本身是没有办法感知到的,那么应该如何让vue知道我们进行了访问或是修改的操作呢?
那就要使用Object.defineProperty
var vm = {}
var data = {
name: 'zhangsan',
age: 20
}
var key, value
for (key in data) {
(function (key) {
Object.defineProperty(vm, key, {
get: function () {
console.log('get', data[key]) // 监听
return data[key]
},
set: function (newVal) {
console.log('set', newVal) // 监听
data[key] = newVal
}
})
})(key)
}
通过Object.defineProperty将data里的每一个属性的访问与修改都变成了一个函数,在函数get和set中我们即可监听到data的属性发生了改变。
Comments NOTHING