浅谈 MVC 和 MVVM 模型
Posted SegmentFault
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈 MVC 和 MVVM 模型相关的知识,希望对你有一定的参考价值。
MVC
那时计算机世界天地混沌,浑然一体,然后出现了一个创世者,将现实世界抽象出模型形成model,将人机交互从应用逻辑中分离形成view,然后就有了空气、水、鸡啊、蛋什么的。
——《前端MVC变形记》
Model(模型)
var myapp = {}; // 创建这个应用对象
myapp.Model = function() {
var val = 0;
this.add = function(v) {
if (val < 100) val += v;
};
this.sub = function(v) {
if (val > 0) val -= v;
};
this.getVal = function() {
return val;
};
/* 观察者模式 */
var self = this,
views = [];
this.register = function(view) {
views.push(view);
};
this.notify = function() {
for( var i = 0; i < views.length; i++) {
views[i].render(self);
}
};
};
View(视图)
myapp.View = function(controller) {
var $num = $( '#num'),
$incBtn = $( '#increase'),
$decBtn = $( '#decrease');
this.render = function(model) {
$num.text(model.getVal() + 'rmb');
};
/* 绑定事件 */
$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);
model.notify();
};
/* 让Model更新数值并通知View更新视图 */
this.increase = function() {
model.add( 1);
model.notify();
};
this.decrease = function() {
model.sub( 1);
model.notify();
};
};
( function() {
var controller = new myapp.Controller();
controller.init();
})();
通讯
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>
ViewModel
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 的框架下视图 View 和模型 Model 是不能直接通信的。它们通过 ViewModel 来通信,ViewModel 通常要实现一个 observer 观察者,当数据发生变化,ViewModel 能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel 也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且 MVVM 中的 View 和 ViewModel 可以互相通信。
Vue 数据双向绑定原理
数据绑定
负责对数据对象的所有属性进行监听 (数据劫持) ,监听到数据发生变化后通知订阅者。
扫描模板,并对指令进行解析,然后绑定指定事件。
关联 Observer 和 Compile,能够订阅并收到属性变动的通知,执行指令绑定的相应操作,更新视图。Update() 是它自身的一个方法,用于执行 Compile 中绑定的回调,更新视图。
数据劫持
var foo = {
name: 'vue',
version: '2.0'
}
function observe(data) {
if (!data || typeof data !== 'object') {
return
}
// 使用递归劫持对象属性
Object.keys(data).forEach( function(key) {
defineReactive(data, key, data[key]);
})
}
function defineReactive(obj, key, value) {
// 监听子属性 比如这里data对象里的 'name' 或者 'version'
observe(value)
Object.defineProperty(obj, key, {
get: function reactiveGetter() {
return value
},
set: function reactiveSetter(newVal) {
if (value === newVal) {
return
} else {
value = newVal
console.log( `监听成功:${value} --> ${newVal}`)
}
}
})
}
observe(foo)
foo.name = 'angular' // “监听成功:vue --> angular”复制代码
以上是关于浅谈 MVC 和 MVVM 模型的主要内容,如果未能解决你的问题,请参考以下文章