js mvc 实现
MVC 模式简介
MVC(Model-View-Controller)是一种软件架构模式,将应用程序分为三个核心组件:模型(Model)负责数据逻辑,视图(View)负责展示,控制器(Controller)处理用户输入和协调模型与视图。
JavaScript 实现 MVC 的核心组件
模型(Model)
模型负责管理数据、业务逻辑和规则。通常包含数据获取、存储和验证方法。
class Model {
constructor(data) {
this.data = data;
}
update(data) {
this.data = { ...this.data, ...data };
// 触发数据变更通知
}
getData() {
return this.data;
}
}
视图(View)
视图负责渲染用户界面,监听用户交互,但不处理业务逻辑。
class View {
constructor(templateId) {
this.template = document.getElementById(templateId).innerHTML;
}
render(data) {
const compiled = this.template.replace(/{{(\w+)}}/g, (_, key) => data[key]);
document.getElementById('app').innerHTML = compiled;
}
}
控制器(Controller)
控制器作为中介,接收用户输入并更新模型或视图。
class Controller {
constructor(model, view) {
this.model = model;
this.view = view;
// 绑定模型变更监听
this.model.onUpdate(() => this.view.render(this.model.getData()));
}
handleUserAction(input) {
this.model.update(input); // 触发模型更新
}
}
完整实现示例
以下是一个简单的待办事项列表(Todo List)实现:
模型定义
class TodoModel {
constructor() {
this.todos = [];
this.listeners = [];
}
addTodo(text) {
this.todos.push({ text, completed: false });
this.notify();
}
onUpdate(callback) {
this.listeners.push(callback);
}
notify() {
this.listeners.forEach(cb => cb(this.todos));
}
}
视图定义
class TodoView {
constructor() {
this.form = document.getElementById('todo-form');
this.list = document.getElementById('todo-list');
}
render(todos) {
this.list.innerHTML = todos.map(todo => `
<li class="${todo.completed ? 'completed' : ''}">
${todo.text}
</li>
`).join('');
}
bindAddTodo(handler) {
this.form.addEventListener('submit', event => {
event.preventDefault();
const input = this.form.querySelector('input');
handler(input.value);
input.value = '';
});
}
}
控制器连接
class TodoController {
constructor(model, view) {
this.model = model;
this.view = view;
this.view.bindAddTodo(this.handleAddTodo.bind(this));
this.model.onUpdate(todos => this.view.render(todos));
}
handleAddTodo(text) {
if (text.trim()) {
this.model.addTodo(text);
}
}
}
初始化应用
const app = new TodoController(
new TodoModel(),
new TodoView()
);
关键注意事项
- 单向数据流:确保数据流动方向为 View → Controller → Model → View
- 事件解耦:使用观察者模式或发布订阅模式实现模型与视图的通信
- 职责分离:避免在视图中包含业务逻辑或在模型中操作DOM
- 现代框架对比:React/Vue等框架虽受MVC启发,但采用更高效的虚拟DOM等机制
扩展方案
对于复杂应用,可考虑以下改进:
- 使用模块化组织代码(ES Modules)
- 引入状态管理库(如Redux)处理跨组件数据
- 实现路由控制器管理不同视图
- 添加中间件机制处理控制器逻辑
以上实现展示了MVC模式在纯JavaScript中的核心思想,实际项目中可根据需求调整架构细节。







