电脑指南
第二套高阶模板 · 更大气的阅读体验

MVC模式三大组件:模型、视图、控制器到底怎么分工?

发布时间:2026-04-04 23:30:52 阅读:5 次

写后台接口时,常听老司机说“这得按MVC来”,可真到自己搭路由,却容易把逻辑全塞进一个文件里——比如把查数据库、拼HTML、判断登录状态全搅和在一起。结果改个按钮颜色,得翻三页代码;加个权限校验,又得在十几个路由里补if语句。

模型(Model):只管数据,不问UI

Model不是数据库本身,而是对数据的操作封装。它不知道页面长啥样,也不关心用户点没点提交按钮。比如一个用户管理模块,Model里只干三件事:查用户、改密码、删账号。

class UserModel {
static findById(id) {
return db.query('SELECT * FROM users WHERE id = ?', [id]);
}
static updatePassword(userId, hash) {
return db.query('UPDATE users SET password = ? WHERE id = ?', [hash, userId]);
}
}

你看,里面没有res.send,没有req.body,连console.log都懒得打——它只负责把数据拿稳、改准、交出去。

视图(View):纯渲染,零逻辑

View就是模板文件,比如EJS、Pug或Vue单文件里的template部分。它只接收数据,然后老老实实画出来。不该在这里调API,不该在这里算时间戳,更不该写if(user.role === 'admin') {...}这种业务判断。

<!-- user-profile.ejs -->
<h1><%= user.name %></h1>
<p>注册时间:<%= formatDate(user.createdAt) %></p>
<button onclick="editProfile(<%= user.id %>)">编辑</button>

注意:formatDate是前端工具函数,不是后端逻辑;onclick调用的是JS方法,不是服务端路由——View的边界就在这里:它只输出HTML,其余一概不管。

控制器(Controller):当好中间人

Controller是路由的实际执行者。它从req里取参数,调Model拿数据,再把结果交给View。就像餐厅服务员:客人(浏览器)点单(发请求),它记下来(解析参数),去后厨(Model)下单,等菜好了(拿到数据),再端上桌(render或json响应)。

app.get('/user/:id', async (req, res) => {
const user = await UserModel.findById(req.params.id);
if (!user) return res.status(404).send('找不到用户');
res.render('user-profile', { user });
});

这里没查数据库细节,没拼HTML字符串,也没做权限拦截——那些该由Model和中间件各司其职。Controller越薄,路由越清爽,后期加缓存、换模板、迁移到SSR都更容易。

你有没有试过把Model里的一行SQL改成NoSQL查询?如果Controller没掺和数据细节,那只要改Model,所有用到它的路由自动生效。这才是MVC在路由调优里的真实价值:不是炫技,是让每次改动,都只动该动的那一小块。