MVC模式的业务逻辑主要集中在Controller,而前端的View其实已经具备了独立处理用户事件的能力,当每个事件都流经Controller时,这层会变得十分臃肿。
MVVM
MVVM简介
核心思想:
分而治之(不同业务代码放到不同业务模块当中,通过特定逻辑组织到一块)
MVVM其实是 M、V、VM,即 Model-View-ViewModel 的缩写。它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得 ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。
啥是Model、View、ViewModel?
Model
可以把Model称为数据层,因为它仅仅关注数据本身,不关心任何行为(格式化数据由View的负责),这里可以把它理解为一个类似json的数据对象,主要存的是页面中的数据。
//可以把它理解为一个类似json的数据对象
var data = {
val: 0
};
Model层代表的是模型、数据,可以在Model层中定义数据修改和操作的业务逻辑。
View
指的是所看到的页面,和MVC/MVP不同的是,MVVM中的View通过使用模板语法来声明式地将数据渲染进DOM,当ViewModel对Model进行更新的时候,会通过数据绑定更新到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>
View层代表的是视图、模版,负责将数据模型转化为UI展现出来。
ViewModel
MVVM模式的核心,它是连接view和model的桥梁。它有两个方向:
- 将Model转化成View,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
- 将View转化成Model,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
这两个方向都实现的,我们称之为数据的双向绑定。
例如:
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的架构下,View层和Model层并没有直接联系,而是通过ViewModel层进行交互。
ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。
ViewModel层通过双向数据绑定将View层和Model层连接了起来,使得View层和Model层的同步工作完全是自动的。因此开发者只需关注业务逻辑,无需手动操作DOM,复杂的数据状态维护交给MVVM统一来管理。
Vue.js中MVVM的体现
Vue.js的实现方式,对数据(Model)进行”劫持“,当数据变动时,数据会触发劫持时绑定的方法,对视图进行更新。
vue中MVVM的体现:
实例分析:
由例子可知ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干预。
Vue.js关于双向数据绑定的一些实现细节
下面我又简单地了解了一下Vue.js关于双向数据绑定的一些实现细节;主要参考了下面这篇文章,很有研究价值,有意向者可以去看一下:深入MVVM模型带你理解Vue.js的双向绑定
vue是采用Object.defineProperty的getter和setter,并结合观察者模式来实现数据绑定的。当把一个普通的javascript对象传给Vue实例来作为它的data选项时,Vue将遍历它的属性,用Object.defineProperty将它们转为getter/setter。用户看不到getter/setter,但是在内部它们让Vue追踪依赖。在属性被访问和修改时通知变化。
vue双向绑定图示:
- Observer数据监听器,能够对数据对象的所有属性进行监听,如有变动可拿到最新的值并通知订阅者,内部采用的Obiect.defineProperty的getter和setter来实现。
- complie指令解析器,它的作用对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定Observer和Complie的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应的回调函数
- Watcher订阅者,作为连接Observer和Complie的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数。
- Dep消息订阅器,内部维护了一个数组,用来收集订阅者(watcher),数据变动触发notify函数,再调用订阅者的update方法。
以上过程可总结为:
Observer相当于Model层观察vue实例中的data数据,当数据发生变化时,通知Watcher订阅者。
Compile指令解析器位于View层,初始化View的视图,将数据变化与更新函数绑定,传给Watcher订阅者。
Watcher是整个模型的核心,对应ViewModel层,连接Observer和Compile。所有的Watchers存于Dep订阅器中,Watcher将Observer监听到的数据变化对应相应的回调函数,处理数据,反馈给View层更新界面视图。
MVC
MVC简介
MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。
MVC的Model、View、Controller
Model(模型)
Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
Model定义了这个模块的数据模型。在代码中体现为数据管理者,Model负责对数据进行获取及存放。
Model既是数据管理者,也由它来负责获取数据,数据不可能凭空生成的,要么是从服务器上面获取到的数据,要么是本地数据库中的数据,也有可能是用户在UI上填写的表单即将上传到服务器上面存放,所以需要有数据来源。既然Model是数据管理者,则自然由它来负责获取数据。
MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。
这里我们把需要用到的数值变量封装在Model中,并定义了add、sub、getVal三种操作数值方法
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);
}
};
}
Model和View之间使用了观察者模式,View事先在此Model上注册,进而观察Model,以便更新在Model上发生改变的数据。
View(视图)
View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
View,视图,简单来说,就是我们在界面上看见的一切。
view和controller之间使用了策略模式,这里View引入了Controller的实例来实现特定的响应策略,比如这个栗子中按钮的 click 事件:
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实例替换即可。
Controller(控制器)
Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
Controller是MVC中的数据和视图的协调者,也就是在Controller里面把Model的数据赋值给View来显示(或者是View接收用户输入的数据然后由Controller把这些数据传给Model来保存到本地或者上传到服务器)
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();
};
};
这里我们实例化View并向对应的Model实例注册,当Model发生变化时就去通知View做更新,这里用到了观察者模式。
当我们执行应用的时候,使用Controller做初始化:
(function() {
var controller = new myapp.Controller();
controller.init();
})();
MVC中的通讯
各部分之间的通信方式如下,所有通讯都是单向的 。
- View 传送指令到 Controller
- Controller 完成业务逻辑后,要求 Model 改变状态
- Model 将新的数据发送到 View,用户得到反馈
接受用户指令时,MVC 可以分成两种方式:
一种是通过 View 接受指令,传递给 Controller:
另一种是直接通过controller接受指令:
MVC模式的业务逻辑主要集中在Controller,而前端的View其实已经具备了独立处理用户事件的能力,当每个事件都流经Controller时,这层会变得十分臃肿。而且MVC中View和Controller一般是一一对应的,捆绑起来表示一个组件,视图与控制器间的过于紧密的连接让Controller的复用性成了问题。
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/tech/25515.html