前言
最近,在和一个同事闲聊的时候被问到MVC和MVVM的区别,说实话,这是一个面试题大军中非常常见的一员,但是之前可能是只是背一下,并没有深入的了解过,所以在被同事问到之后,我突然语塞了,不知道该如何作答,当时感觉还是挺羞愧的,所以为了弥补我这方面的漏洞,我深入的了解了一下MVVM和MVC
MVC
首先说一下MVC,MVC分为三层,Model(模型层)、View(视图层),Controller(控制层),其实简单来说,MVC可以总结为一句话,Controller负责将Model的数据渲染在View中(就是如此简单)。但是仔细理解起来还是有些费时间的,下面我们就一一讲解下MVC这三层
- View层是最上面的一层(显示层),是直接面对用户的,它将操作界面提供给用户
- Controller层是中间的一层(操作层), 是控制层,主要是用于处理数据,根据View层不同的指令来"选取"Model层的数据,然后对其进行相应的操作,返回相应的数据
- Model层是最下面的一层(数据层),即程序所需要的数据等
三层紧密联系,但是却又互不干扰,只通过接口进行交互,
三者之间的关系是user --> view ---> controller --->Model-->view(这里我没有找一张图附上),所以view层和Model层是没有直接进行交互的,而是通过controller层进行交互的
MVC的优点
下面我只说一些常见的
-
低内聚
这个词相信大家都不会陌生,在软件工程中我们总是说高耦合,低内聚,所谓的低内聚到底是什么意思呢,低内聚表示各个模块之间的联系要尽量的少
-
可维护性高
由于将视图层和业务逻辑层分开,所以我在维护上也变得更加容易
MVC的缺点
至于MVC的缺点,其实说起来可能比较高大上一点,能兴趣的可以看下
- 增加了系统结构的复杂性,毕竟现在一个项目是拆分成三层的,所以在结构上肯定会比较复杂
- view层对model的数据低效率访问,因为view层只能通过controller层对model的数据进行访问
MVVM
讲完MVC了,我们再来讲讲MVVM,首先,大家肯定会有疑问,为什么有了MVC,还会出现MVVM呢,其实原因是MVC是允许Model和View直接通信的,当随着业务量变大的时候,这块的逻辑依赖肯定会变得复杂,同时这要是MVVM模式设计的出发点, 下面我们来看看MVVM,MVVM也是分为三层,View(视图层), Model(数据层), ViewModel(中间层)
- View层,这个和上面MVC中的view层的作用是一样的
- Model层,也是数据层
- ViewModel层,这层其实只是起一个桥梁的作用,主要是用于将View层的修改同步到Model,把Model层的数据显示到View层
MVVM的中心思想(数据驱动)
- 响应式
- 模板解析
- 渲染
响应式
什么是响应式呢,又是怎么实现响应式的呢 首先响应式就是通过数据驱动渲染View层的界面,它是怎么做到的呢,像我们正常修改数据,怎么能通过到view层我们的数据改变了呢,其实底层主要是通过一个函数实现的,就是Object.defineProperty()实现的
var people = {
name: 'pwz',
age: 18
}
var vm = {}
var key
var value
for(let i in people) {
(function(key){
Object.defineProperty(vm, key, {
get: function() {
return people[key]
},
set: function(newVal) {
people[key] = newVal
}
})
})(key)
}
模板解释
模板的本质上就是字符串,但是模板上还有一系列的逻辑指令等等,如果我们在普通的html上写一个v-for的指令,这肯定是不生效的,所以我们在这里要介绍一个函数,render函数,(render函数的底层是with函数,但是这个函数现在已经不推荐使用了),通过render函数我们最终生成一个虚拟DOM
渲染
如何将虚拟DOM渲染成html呢,此时分为两种情况,第一种就是初次渲染的时候,第二种就是数据更新的时候,此时会调用updateComponent方法
vm._update(vnode){
const prevVnode = vm._vnode
vm._vnode = vnode
if (!prevVnode){
vm.$el = vm.__patch__(vm.$el,vnode)
} else {
vm.$el = vm.__patch__(prevVnode,vnode)
}
}
function updateComponent(){
vm._update(vm._render())
}
首先会读取虚拟dom,判断其是否为空,如果为空,则为初次渲染,将虚拟dom全部渲染到页面,若不为空,则是数据发生了修改,通过响应式我们可以监听到这一情况,使用diff算法完成新旧对比并修改
MVC和MVVM的区别
- MVVM的View和Model是不能直接交互的
- MVVM通过数据来驱动视图,用户只需要关心数据的变化即可