视图(View):用户界面。
控制器(Controller):业务逻辑
模型(Model):数据操作
V -> C -> M -> C -> V。
Model:即数据模型,用来包装和应用程序的业务逻辑相关的数据或者对数据进行处理,模型可以直接访问数据。表示着业务逻辑和数据,模型把这些数据逻辑渲染到 View 中,比较常见的做法是后端的模版技术,例如 jsp 之类的,把预期的数据填入 jsp 模版中,返回给浏览器。当然,像现在的 restful 应用中,前端都为 SPA 单页面应用,那么 api 返回的 json 数据也相当于为 View。
View:视图用来有目的显示数据,在视图中一般没有程序上的逻辑,为了实现视图上的最新功能,视图需要访问它监视的数据模型。负责 UI 渲染工作,传统的 MVC 中,一个 View 就是一个 Web 页面,通常还有有 Javascript 代码在其中负责一些页面逻辑。
Controller:控制器调控模型和视图的联系,它控制应用程序的流程,处理事件并作出响应,事件不仅仅包括用户的行为还有数据 模型上的改变。通过捕获用户事件,通知模型层作出相应的更新处理,同时将模型层的更新和改变通知给视图,使得视图作出相应改变。因此控制器保证了视图和模型的一致性。
Controller 控制器就相当于一个分发的工具,熟悉 Spring 的同学肯定就知道这就是 Spring 中的 @Controller,一个请求进来,需要什么样的 Model,获取什么样的数据,返回什么样的页面,都是 Controller 的工作。
一般来说,MVC 中的数据流动是单向的,Model 用数据来渲染 View,View 用户界面交互完成后更新数据,然后 Controller 做分发和控制。但是从交互的角度来看并不是单向的,有些情况下,Controller 当收到更新数据请求的时候,Controller 会更新数据,更新完就会重定向到的 View ,View 拿到更新完的 Model 数据,进行渲染,Controller 多充当了一个调度者的角色。
MVP 模式将 Controller 改名为 Presenter(主持人),同时改变了通信方向。
MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Vue 采用这种模式。
功能:select 选择器选择哪个展示哪个
<select id="drinkSelect">
<option value="coffee">coffee</option>
<option value="milk">milk</option>
<option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>
<script type="text/javascript">
document.getElementById("drinkSelect").onchange = function() {
var color;
var colorOfDrink = {
"coffee":"brown",
"milk":"white",
"juice":"orange"
};
color = colorOfDrink[this.value];
document.getElementById("theColorOfDrink").innerHTML = color;
}
</script>
改为 MVC
<select id="drinkSelect">
<option value="coffee">coffee</option>
<option value="milk">milk</option>
<option value="juice">juice</option>
</select>
<p id="theColorOfDrink"></p>
<script type="text/javascript">
//showDrinkColor is Controller
var showDrinkColor = {
start:function(){
this.view.start();
},
set:function(drinkName){
this.model.setDrink(drinkName);
}
};
//Model
showDrinkColor.model = {
colorOfDrink:{
"coffee":"brown",
"milk":"white",
"juice":"orange"
},
selectedDrink:null,
setDrink:function(drinkName){
this.selectedDrink = this.colorOfDrink[this.selectedDrink]?drinkName:null;
this.onchange();
},
onchange:function(){
showDrinkColor.view.update();
},
getDrinkColor:function(){
return this.selectedDrink?this.colorOfDrink[this.selectedDrink]:"white";
}
};
//View
showDrinkColor.view = {
start:function(){
document.getElementById("drinkSelect").onchange = this.onchange;
},
onchange:function(){
showDrinkColor.set(document.getElementById("drinkSelect").value);
},
update:function(){
document.getElementById("theColorOfDrink").innerHTML = showDrinkColor.model.getDrinkColor();
}
};
showDrinkColor.start();
</script>
如果把整个 web 开发看做一个整体,那么前后端不分离时期的 MVC:
如果把整个 web 开发看做一个整体,那么前后端分离时期的 MVC:
对于纯web后台的,MVC是:
对于纯前端的,MVC是: