上期讲了「后端 MVC」,本期讲「前端 MVC」。
前后端分离
前端 MVC 就要从前后端分离讲起了。
前后端分离是指
一个页面分为两部分,浏览器上面的工作交给前端做,服务器上面的工作交给后端做(人员分离)
页面开发流程是这样的
1. 浏览器第一次加载的页面只是一个占位符,比如这样
<body>
<div id=app></div>
</body>2. 前端将其他 HTML 和从服务器获取的数据填到占位符里
伪代码:
$.get('/user/1').then(function(user){
template = (
<h1>{{ name }}</h1>
)
content = template.replace('{{ title }}', user.name)
$app.html(content)
})
3. 用户提交数据时,前端用 AJAX 提交异步请求
$form.on('submit', function(){
$.post('/user/1', $form.serialize()).then(function(){
alert('提交成功')
})
})
老司机的总结

前端老司机发现自己每个项目都要重复上面的流程,于是也想总结一下,归纳一下,抽象一下。
假设我们要做一个用户中心页面。
Model - 封装数据操作
对用户的增删改成其实都是异步请求,我能不能封装到一起呢?
var userModel = {
find: function(id){
return $.get('/user/'+id).then(function(user){
$.extend(userModel, user)
})
},
save: function(id, data){
return $.post('/user/'+id, data)
}
}出了这些,还有用户数据的校验
userModel.validate = function(){
if(this.name === '') return false
if(this.password === '') return false
return true
}这样一来,数据相关的操作就都放到这个 model 上了。
View - 视图渲染
前端的视图也是 HTML,由于 HTML 里面没有数据,所以我们一般都要将数据与 HTML 混合起来。
上面代码是这样做混合的:
content = template.replace('{{ title }}', user.name)
显然这样的方案功能不够强大,于是前端们用正则写出很多强大的模板引擎,如 Handlebars.js、React,最终实现的效果大致是:
content = templateEngine( template, user )content 就是带有数据的 HTML 了。
Controller - 控制器主要是打杂的
还有哪些事情没做,都交给 Controller 吧:
- 将 content 塞到页面里
- 浏览器事件监听 - 用户点击视图后去更新数据(如 user)
- 数据事件监听 - user 数据更新后去更新视图
对应的代码:
controller = {
model: userModel,
element: $app,
template: '<h1>{{ name }} </h1>........',
events: {
'click button': 'onButtonClick',
'submit form' : 'onSubmitForm'
},
modelEvents: {
'update': 'onModelUpdate',
'remove': 'onModelRemove'
},
init: function(){
var content = templateEngine(this.template, userModel)
this.element.append($app)
// 遍历 events 并绑定对应的方法
// 遍历 modelEvents 并绑定对应的方法
},
onButtonClick: function(){...},
onSubmitForm: function(){...},
onModelUpdate: function(){...},
onModelRemove: function(){...}
}总结一下:
- Controller 监听 Model 变化,Model 一变,Controller 就会去更新 View。
- Controller 监听用户交互,用户点了提交或修改按钮,Controller 就要去更新 Model。
注意,一个页面可以有多个 Controller,每个 Controller 负责一个大 div 即可。
Router - 路由
前端 MVC 有路由吗?可以有,也可以没有。
如果只是在每个页面局部使用 MVC,那么就不需要路由。
如果整站是一个单页面,那么就要处理 URL 的变化了(用 PushState API 或者 URL Hash)。
MVC 里面最复杂的部分是 Controller,它做了太多机械的、繁琐的事情,比如绑定事件、更新 DOM、更新数据,这也为前端 MVC 没落留下了隐患,后面的 MVP、MVVM、FLUX 很好地解决这一问题(同时引入了其他问题)。不过 MVC 的概念,我们还是有必要了解的。
欢迎进群与我探讨技术,戳此扫码加微信进程序员分享交流群。
本文作者方应杭,未经同意禁止转载,转载请联系本人并加上版权声明和本文链接。