前端常用设计模式主要分为创建型、结构型、行为型三类,都是日常写Vue/React/原生JS都会用到的核心模式。
一、创建型模式(控制对象创建)
1. 单例模式(Singleton)
核心:一个类只创建一个实例,全局共享访问。 前端应用:全局弹窗、全局状态管理、日志工具、请求封装实例。
// 全局弹窗单例(实际项目常用)
class GlobalModal {
static instance = null;
constructor() {
if (GlobalModal.instance) return GlobalModal.instance;
this.modal = document.createElement('div');
this.modal.className = 'global-modal';
document.body.appendChild(this.modal);
GlobalModal.instance = this;
}
show(content) {
this.modal.innerHTML = content;
this.modal.style.display = 'block';
}
}
// 使用:无论new多少次,都是同一个弹窗
const modal1 = new GlobalModal();
const modal2 = new GlobalModal();
console.log(modal1 === modal2); // true
实际业务:Element Plus 的 ElMessage、全局请求实例 axios.create 都是单例。
2. 工厂模式(Factory)
核心:封装对象创建逻辑,根据不同条件创建不同对象。 前端应用:表单组件工厂、权限控制、不同类型的弹窗/卡片渲染。
// 表单组件工厂:根据类型生成输入框/单选框/下拉框
class FormFactory {
static create(type, options) {
switch (type) {
case 'input': return new Input(options);
case 'radio': return new Radio(options);
case 'select': return new Select(options);
default: throw new Error('不支持的组件类型');
}
}
}
// 业务使用:一行代码创建不同组件
const usernameInput = FormFactory.create('input', { placeholder: '请输入用户名' });
const genderRadio = FormFactory.create('radio', { options: ['男', '女'] });
实际业务:低代码平台、动态表单、根据用户角色渲染不同页面模块。
二、结构型模式(组合对象/代码结构)
1. 适配器模式(Adapter)
核心:兼容两个不兼容的接口,不用修改原有代码。 前端应用:接口数据格式转换、第三方SDK兼容、新旧API适配。
// 场景:后端返回旧数据格式,前端需要新格式
// 旧接口数据
const oldApiData = { userName: "张三", userAge: 20 };
// 前端需要的格式
const newDataFormat = { name: "", age: 0 };
// 适配器:转换格式
function userAdapter(data) {
return {
name: data.userName,
age: data.userAge
};
}
// 使用
const adaptedData = userAdapter(oldApiData);
console.log(adaptedData); // { name: "张三", age: 20 }
实际业务:对接多个后端接口、兼容不同版本的UI库、微信/支付宝支付SDK统一适配。
2. 装饰器模式(Decorator)
核心:不修改原对象/函数,动态添加功能。 前端应用:函数增强、埋点统计、权限校验、日志打印。
// 原按钮点击函数
function submit() { console.log("提交表单"); }
// 装饰器:添加埋点功能
function withTrack(fn) {
return function() {
console.log("上报埋点:submit_click"); // 新增功能
fn.apply(this, arguments); // 执行原逻辑
}
}
// 装饰后的函数
const submitWithTrack = withTrack(submit);
submitWithTrack();
// 输出:上报埋点:submit_click → 提交表单
实际业务:Vue 自定义指令、React HOC、请求拦截/响应拦截、按钮防抖/节流封装。
3. 代理模式(Proxy)
核心:控制对原对象的访问,做拦截、校验、缓存。 前端应用:Vue3 响应式原理、图片懒加载、接口缓存、权限拦截。
// Vue3 响应式核心原理(简化版)
const target = { name: "前端开发" };
const proxy = new Proxy(target, {
get(target, key) {
console.log(`获取属性:${key}`);
return Reflect.get(target, key);
},
set(target, key, value) {
console.log(`设置属性:${key} = ${value}`);
return Reflect.set(target, key, value);
}
});
proxy.name; // 获取属性:name
proxy.name = "设计模式"; // 设置属性:name = 设计模式
实际业务:图片懒加载代理、敏感数据加密、接口请求缓存、防重复点击。
4. 组合模式(Composite)
核心:将对象组合成树形结构,统一处理单个对象和组合对象。 前端应用:树形菜单、文件目录、表单嵌套、组件树渲染。
// 树形菜单:叶子节点 + 父节点统一调用render()
class MenuItem {
constructor(name) { this.name = name; }
render() { console.log("渲染菜单项:", this.name); }
}
class MenuGroup {
constructor(name) {
this.name = name;
this.children = [];
}
add(item) { this.children.push(item); }
render() {
console.log("渲染菜单组:", this.name);
this.children.forEach(item => item.render());
}
}
// 使用:组合成树形结构
const rootMenu = new MenuGroup("主菜单");
rootMenu.add(new MenuItem("首页"));
const subMenu = new MenuGroup("用户中心");
subMenu.add(new MenuItem("个人信息"));
rootMenu.add(subMenu);
rootMenu.render(); // 统一渲染整个树
实际业务:Vue/React 组件树、文件管理器、多级审批流。
三、行为型模式(对象间通信/逻辑)
1. 观察者模式(Observer)
核心:一对多依赖,一个对象变化,所有依赖者自动更新。 前端应用:事件监听、Vue/React 状态更新、消息订阅。
// 简易事件总线(Vue2 EventBus 原理)
class EventBus {
constructor() { this.events = {}; }
// 订阅事件
on(eventName, callback) {
if (!this.events[eventName]) this.events[eventName] = [];
this.events[eventName].push(callback);
}
// 发布事件
emit(eventName, data) {
this.events[eventName]?.forEach(cb => cb(data));
}
}
// 使用
const bus = new EventBus();
bus.on("login", (user) => console.log("用户登录:", user));
bus.emit("login", { name: "张三" });
实际业务:Vue 响应式、Redux 状态更新、WebSocket 消息推送、跨组件通信。
2. 发布-订阅模式(Publish-Subscribe)
和观察者区别:多了中间调度中心,解耦发布者和订阅者。 前端应用:全局消息通知、跨页面通信、模块化解耦。
日常开发中,EventBus 同时实现了发布-订阅模式,用法和上面一致。
3. 策略模式(Strategy)
核心:将算法/逻辑封装成策略,动态切换,避免大量 if-else。 前端应用:表单校验、支付方式切换、权限判断、打折计算。
// 表单校验策略:替换一堆if-else
const validateStrategies = {
required: (val) => val ? true : "必填项不能为空",
phone: (val) => /^1[3-9]\d{9}$/.test(val) ? true : "手机号格式错误",
email: (val) => /^.+@.+\..+$/.test(val) ? true : "邮箱格式错误"
};
// 使用
console.log(validateStrategies.required("")); // 必填项不能为空
console.log(validateStrategies.phone("13800138000")); // true
实际业务:登录表单校验、电商优惠计算、不同支付渠道(微信/支付宝/银行卡)切换。
4. 迭代器模式(Iterator)
核心:顺序遍历集合,不用关心内部结构。 前端应用:数组遍历、Tree 数据遍历、自定义遍历逻辑。
// JS 原生已实现:for...of 就是迭代器
const arr = [1,2,3];
for (const item of arr) { console.log(item); }
// 自定义迭代器:遍历树形数据
function* treeIterator(tree) {
for (const node of tree) {
yield node;
if (node.children) yield* treeIterator(node.children);
}
}
实际业务:树形数据递归遍历、列表无限滚动、自定义数据遍历。
5. 命令模式(Command)
核心:将请求封装成命令对象,支持撤销/重做/队列执行。 前端应用:编辑器撤销重做、操作日志、任务队列。
// 命令对象:执行 + 撤销
class Command {
constructor(execute, undo) {
this.execute = execute;
this.undo = undo;
}
}
// 文本编辑命令
const addText = new Command(
(str) => console.log("添加文字:", str),
(str) => console.log("撤销文字:", str)
);
addText.execute("Hello"); // 添加文字:Hello
addText.undo("Hello"); // 撤销文字:Hello
实际业务:富文本编辑器、流程图操作撤销/重做、后台任务队列。
四、前端专属高频模式
1. 模块模式(Module)
核心:私有化变量,避免全局污染。 应用:原生JS模块化、IIFE、ES6 Module。
// ES6 模块天然支持私有化
const privateVar = "私有变量"; // 外部无法访问
export const publicFunc = () => console.log(privateVar);
2. 中介者模式(Mediator)
核心:对象间不直接通信,通过中介者统一调度。 应用:表单联动、多组件状态同步、聊天室。
五、快速选型指南
| 业务场景 | 推荐设计模式 |
|---|---|
| 全局唯一工具/弹窗 | 单例模式 |
| 动态创建组件/表单 | 工厂模式 |
| 接口数据格式转换 | 适配器模式 |
| 避免if-else/逻辑切换 | 策略模式 |
| 组件通信/状态更新 | 观察者/发布订阅 |
| 权限/缓存/拦截 | 代理模式 |
| 树形结构/组件树 | 组合模式 |
| 函数增强/埋点 | 装饰器模式 |
总结
- 不用死记硬背:前端设计模式是解决实际问题的套路,记住「场景→模式」对应关系即可;
- 框架底层都在用:Vue3(Proxy)、React(HOC)、Redux(观察者)、EventBus(发布订阅);
- 核心价值:代码可维护、可扩展、解耦、少写if-else,提升开发效率和代码质量。