MVC,MVP,MVVM是三种常见的前端架构模式(Architectural Pattern),它通过分离关注点来改进代码组织方式。不同于设计模式(Design Pattern),只是为了解决一类问题而总结出的抽象方法,一种架构模式往往能使用多种设计模式。
MVC模式是MVP,MVVM模式的基础,这两种模式更像是MVC模式的优化改良版,他们三个的MV即Model,view相同,不同的是MV之间的纽带部分。本文主要介绍MVC与MVVM的应用与区别,因为MVP好像不是很常用。
二.MVC
简介一下MVC:
![](https://box.kancloud.cn/74c15299733dc271ccba753f910d7852_378x279.png)
MVC允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。
如果前端没有框架,只使用原生的html+js,MVC模式可以这样理解。将html看成view;js看成controller,负责处理用户与应用的交互,响应对view的操作(对事件的监听),调用Model对数据进行操作,完成model与view的同步(根据model的改变,通过选择器对view进行操作);将js的ajax当做Model,也就是数据层,通过ajax从服务器获取数据。
按照上面这种方式分层,感觉多少有点强行MVC,因为Model层被弱化了。我们可以看看其他主流MVC框架是怎么分层的,拿BackBone举例。
首先简单介绍一下backbone,它是一个轻量级前端MVC框架,用于结构化管理页面中大量的js(就是管理大量js文件的项目更适用),建立与服务器,视图间的无缝连接,为构建复杂应用提供基础架构。backbone里面包含Model,View,Collection,Router等模块。这里的Model和View与MVC模式的Model和View有区别,我们先看Model。
```
var M = Backbone.Model.extend({
defaults:{name:"hello"} ,
initialize : function(){ //new M时,会执行这个初始化函数。
this.on("change",function(){ //监听change事件
alert(1);
})
}
})
var model = new M();
```
model.set("name","hi"); //改变模型的name值时,就会触发change事件,弹出1.其实这里只要改变模型,就会触发。
这里Model的对象不只包含数据,也有对属性(name)的监听事件。所以backbone里的Model也不是纯Model,它有一部分Controller的功能。
我们再看看Backbone的View
```
var M = Backbone.Model.extend({
defaults:{name:"hello"}
});
var V = Backbone.View.extend({
initialize:function(){ //new V时,会跟这个视图的model绑定change事件,回调方法是视图的show方法
this.listenTo(this.model, "change", this.show); //listenTo方法跟on一样是绑定事件的,但是listenTo可以设置this的指向,它多一个参数。它的意思就是:给this.model绑定change事件。
},
show:funtion(model){
$("#tt").append(this.model.name);
}
});
var m= new M();
var v = new V({model:m});
```
m.set("name","hi"); //改变模型的name值时,就会触发change事件,在视图中弹出模型设置的name值。
这里view即包含了视图显示也包含了事件监听,属于传统的View+Model。
综上可以看出,backbone这样的MVC框架,Model和View的概念很突出,Controller主要放在了View里面。这种模式更好理解,Model看成模型,View看成这个模型的视图化体现,而Controller根据需要写在各自的方法里。这么一看MVC还是挺好的,那为什么有MVVM这种改良版本呢?
三.MVVM
![](https://box.kancloud.cn/cf1408179b22cd06cb153688d97d4ae0_375x270.png)
MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。非常的神奇~
这里我们拿典型的MVVM模式的代表,Vue,来举例
```
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
```
这里的html部分相当于View层,可以看到这里的View通过通过模板语法来声明式的将数据渲染进DOM元素,当ViewModel对Model进行更新时,通过数据绑定更新到View。
Vue实例中的data相当于Model层,而ViewModel层的核心是Vue中的双向数据绑定,即Model变化时VIew可以实时更新,View变化也能让Model发生变化。
整体看来,MVVM比MVC精简很多,不仅简化了业务与界面的依赖,还解决了数据频繁更新的问题,不用再用选择器操作DOM元素。因为在MVVM中,View不知道Model的存在,Model和ViewModel也观察不到View,这种低耦合模式提高代码的可重用性。
四.总结
在学习MVC与MVVM架构模式的过程中,经常会对分层的界限叫不准。比如说不清楚js里到底哪里算Model,哪里算Controller,Vue实例里面Model与ViewModel的严格界限在哪,有时候越想越感觉叫不准。当我从头到尾整理完这两种模式特点的时候,发现这个界限没有那么重要。我觉得重要的是,理解两种模式的基本思想,根据应用需求,选择适合自己业务的框架。MVVM自然有很多先进的地方,但有的项目选择BackBone可能会更适合。在实践中比较两种模式的各个框架的优缺点,选择适合自己的架构模式,更有利于项目的高效开发。
- 面试自我介绍
- 面试常规题
- HTML,CSS
- 1.动画animation有哪些属性及其基本使用
- 2.transform有哪些属性及其基本使用
- 3.::before 和 :after中双冒号和单冒号 有什么区别
- 4. 如何实现一个元素的垂直水平居中
- 5. position的值relative和absolute定位原点是?
- 6. 用纯CSS创建一个三角形的原理是什么?
- 7. title与h1的区别、b与strong的区别、i与em的区别?
- 8. 使用 CSS 预处理器吗?喜欢那个?
- 9. 如果需要手动写动画,你认为最小时间间隔是多久,为什么?
- 10. 对HTML5的了解
- 11. img与文本之间的留白
- 12. 给唯一子元素margin-top,父元素跟随移动
- 13. 什么是重构和架构
- 14. css选择器的优先级别
- JavaScript
- 1. js变量声明提升
- 2.数组的方法有哪些?这些方法中不改变原数组的有哪些?
- 3. 理解undefined 和 null 区别
- 4. http与https的区别
- 5.https的原理及其局限性
- 6. let/const/var的区别
- 7. JS的内存机制与垃圾回收机制
- 8. 值类型和引用类型的区别
- 9. document.writer和innerHTML
- 10. document.ready和window.onload的区别
- 11. js有几种方法创建一个对象
- 12. 什么是面向对象?其三大特性是什么?
- 13. 数组遍历的方法
- 14. js字符串反转
- 15. 类型转换
- 1. 如何JSON对象转为字符串
- 2. 字符串转化为数字
- 3. 数组与字符串之间的相互转换
- 16. 深拷贝和浅拷贝的区别
- 17. DOM的加载顺序
- 18. call、apply、bind的区别
- 19. ES5和ES6中类的实现
- 10. new操作符的作用
- 21. 事件冒泡和事件捕获
- 22. 同步和异步
- 23. this关键字怎么理解
- 浏览器以及服务端
- 1. 前端开发有哪些优化问题
- 2. AJAX请求总共有多少种CALLBACK
- 3. 输入URL到看到页面发生的全过程
- 4. CSS和JS的位置会影响页面效率
- 5. 前端页面有哪三层
- 6. 说一下浏览器的缓存机制
- 7. 对web标准及w3c的了解和认识
- 8. 什么是路由
- 9. 状态码
- 10. 浏览器内核
- 11. MVC和MVVM的区别
- 12. cookie、session的区别
- 算法
- 1. 如何判断一个对象是否为数组
- 2. 数组去重的方法
- 3. 数组排序
- 4. 数组去重
- 5. 反转数组
- 6. 数组复制
- 7. 取偶数
- 8. 字符串去重
- 全局性问题
- 1. 谈谈对前端模块化的理解
- 2. 移动布局的单位rem,vw,rpx等
- 3. css 动画和 js 动画的差异
- 4. 谈谈对ES6的理解
- 网络数据请求
- 1. 原生Ajax请求
- 2. jQuery-Ajax请求
- 3. Vue-Ajax请求
- 4. React-Ajax请求
- vue和react
- 1. vuex的工作流
- 2. redux工作流