1. 单例模式(Singleton Pattern)
核心思想
- 一个类只能有一个实例,并提供一个全局访问点。
场景
- 全局缓存
- Vuex / Redux 中的 store
- 浏览器中的 localStorage 管理类
示例
const Singleton = (function () {let instance;function createInstance() {return { name: "我是唯一的实例" };}return {getInstance: function () {if (!instance) {instance = createInstance();}return instance;}};
})();const a = Singleton.getInstance();
const b = Singleton.getInstance();
console.log(a === b); // true
2. 工厂模式(Factory Pattern)
核心思想
- 不直接使用 new 去创建对象,而是通过一个工厂函数根据条件返回不同的实例。
场景
- 创建大量结构相似的对象
- 根据不同参数创建不同对象
示例
function AnimalFactory(type) {switch (type) {case 'dog':return { sound: () => console.log("汪汪") };case 'cat':return { sound: () => console.log("喵喵") };default:return { sound: () => console.log("未知动物") };}
}const dog = AnimalFactory('dog');
dog.sound(); // 汪汪//封装new
function AnimalFactory(type) {if (type === 'dog') return new Dog();if (type === 'cat') return new Cat();throw new Error("Unknown type");
}const pet1 = AnimalFactory('dog'); // 外部不再直接 new
const pet2 = AnimalFactory('cat');
3. 策略模式(Strategy Pattern)
核心思想
- 定义一系列算法,把它们封装起来,并且可以互相替换。
场景
- 表单验证
- 多种支付方式选择
- AI 策略切换
示例
const strategies = {isNotEmpty: val => val !== '',isMobile: val => /^1[3-9]\d{9}$/.test(val),minLength: (val, len) => val.length >= len
};function validate(rule, val, ...args) {return strategies[rule](val, ...args);
}console.log(validate('isMobile', '13888888888')); // true
4. 观察者模式(Observer Pattern)
核心思想
- 对象维护一个观察者列表,当自身状态发生变化时,主动通知这些观察者。
- 解耦发布者与订阅者之间的关系,实现一对多的通知机制。
角色
- Subject(目标对象):被观察的对象,维护一个观察者列表
- Observer(观察者):订阅目标对象的变化,目标对象变化后会通知观察者
场景
- Vue 的响应式数据
- 发布订阅
- DOM 事件系统
示例
class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}notify(data) {this.observers.forEach(observer => observer.update(data));}
}class Observer {constructor(name) {this.name = name;}update(data) {console.log(`${this.name} 收到通知:`, data);}
}const subject = new Subject();
subject.addObserver(new Observer("A"));
subject.addObserver(new Observer("B"));subject.notify("状态变更啦!");
//A 收到通知: 状态变更啦!
//B 收到通知: 状态变更啦!
5.中介者模式(Mediator Pattern)
核心思想
- 避免多个对象之间形成网状结构,实现对象之间的解耦协作。
角色
- Mediator(中介者):封装对象之间的通信,处理对象之间的交互逻辑
- Colleague(同事类):不再相互通信,而是和中介者打交道
示例
class Mediator {constructor() {this.users = {};}register(user) {this.users[user.name] = user;user.mediator = this;}send(message, from, to) {if (this.users[to]) {this.users[to].receive(message, from);}}
}class User {constructor(name) {this.name = name;this.mediator = null;}send(message, to) {this.mediator.send(message, this.name, to);}receive(message, from) {console.log(`${this.name} 收到来自 ${from} 的消息: ${message}`);}
}const mediator = new Mediator();
const alice = new User("Alice");
const bob = new User("Bob");mediator.register(alice);
mediator.register(bob);alice.send("Hi Bob", "Bob");
6. 装饰器模式(Decorator Pattern)
核心思想
- 不修改原有对象结构的前提下,动态扩展其功能。
场景
- Vue 的组件装饰器(@Component)
- 对函数、方法添加日志、缓存、权限控制等
示例
function logDecorator(fn) {return function (...args) {console.log("调用前:", args);const result = fn.apply(this, args);console.log("调用后:", result);return result;}
}function sum(a, b) {return a + b;
}const decoratedSum = logDecorator(sum);
decoratedSum(1, 2);
// 调用前:[1, 2]
// 调用后:3
7. 代理模式(Proxy Pattern)
核心思想
- 通过一个代理对象控制对另一个对象的访问。
场景
- 数据拦截与监控(如 Vue3 响应式 Proxy)
- 图片懒加载
- 网络请求代理
示例
const target = {name: "qiqi",age: 28
};const proxy = new Proxy(target, {get(obj, prop) {console.log("访问属性:", prop);return obj[prop];},set(obj, prop, value) {console.log(`设置 ${prop} 为 ${value}`);obj[prop] = value;return true;}
});proxy.name; // 访问属性:name
proxy.age = 30; // 设置 age 为 30
8. 外观模式(Facade Pattern)
核心思想
- 提供一个统一的接口,屏蔽复杂系统的内部细节。
场景
- 封装复杂 API
- 统一调用入口
- 浏览器兼容性封装
示例
function ajaxFacade(url, method, data) {return fetch(url, {method,headers: { 'Content-Type': 'application/json' },body: JSON.stringify(data)}).then(res => res.json());
}// 使用
ajaxFacade('/api/login', 'POST', { name: 'qiqi' });
9. 发布订阅模式(Publish-Subscribe Pattern)
核心思想
- 通过事件中心管理多个对象之间的通信,发布者与订阅者之间不直接关联。
与观察者模式类似,但通过中间调度器来解耦。
场景
- 事件总线 EventBus
- 跨组件通信
- 消息队列
示例:JS 中的自定义实现
const EventBus = {events: {},on(event, handler) {if (!this.events[event]) this.events[event] = [];this.events[event].push(handler);},emit(event, data) {(this.events[event] || []).forEach(fn => fn(data));}
};EventBus.on('login', data => console.log("登录成功:", data));
EventBus.emit('login', { user: 'qiqi' }); //登录成功: { user: 'qiqi' }
在 Vue 中用法
创建 EventBus 实例:
// event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();
在组件 A 中监听事件(订阅):
// ComponentA.vue
import { EventBus } from './event-bus';export default {created() {EventBus.$on('sayHello', (msg) => {console.log('收到消息:', msg);});},beforeDestroy() {EventBus.$off('sayHello'); // 清除监听}
}
在组件 B 中发送事件(发布):
// ComponentB.vue
import { EventBus } from './event-bus';export default {methods: {sendMsg() {EventBus.$emit('sayHello', '你好,我是B组件');}}
}
Vue 源码中的 EventsMixin (精简):
function EventsMixin(Vue) {Vue.prototype.$on = function (event, fn) {const vm = this;if (!vm._events) vm._events = {};if (!vm._events[event]) vm._events[event] = [];vm._events[event].push(fn);}Vue.prototype.$emit = function (event, ...args) {const vm = this;const cbs = vm._events && vm._events[event];if (cbs) {cbs.forEach(cb => cb(...args));}}Vue.prototype.$off = function (event, fn) {const vm = this;if (!vm._events) return;// 省略部分逻辑,只保留关键流程if (!fn) {delete vm._events[event];} else {vm._events[event] = vm._events[event].filter(cb => cb !== fn);}}
}
Vue2 中常用的设计模式
- 观察者模式(Observer Pattern)
- 用途:实现响应式系统。
- 核心机制:Dep 和 Watcher。
- 数据变化 → 通知订阅者(watcher) → 更新视图。
关键代码:
Object.defineProperty(obj, 'key', {get() {// 依赖收集},set(newVal) {// 通知 watcher 更新}
});
-
发布-订阅模式(Publish-Subscribe)
- 用途:事件总线(EventBus)。
- 用于组件间通信,特别是没有父子关系的组件。
- 实现方式:通过 $on、$emit、$off 方法注册、触发和注销事件。
- 用途:事件总线(EventBus)。
-
工厂模式(Factory Pattern)
- 用途:创建组件实例、VNode 等。
- 示例:Vue.extend() 实际上就是创建一个“组件构造器”。
Vue3 中常用的设计模式
- 观察者模式(Observer Pattern)
- 用途:响应式系统升级为 Proxy。
- 与 Vue2 区别:用 Proxy 替代了 Object.defineProperty,更强大、无死角。
- 核心机制:effect()、reactive()、track()、trigger()。
- 组合模式(Composite Pattern)
- 用途:组合式 API(Composition API)。
- 将逻辑组合成小函数(setup() 中的 hooks),类似树状结构组织功能逻辑。
- 更灵活地组合复用功能。
- 用途:组合式 API(Composition API)。
- 代理模式(Proxy Pattern)
- 用途:响应式对象封装。
const state = reactive({ count: 0 });
reactive 返回的对象是 Proxy 的代理,拦截读写操作。
- 依赖注入模式(DI Pattern)
- 用途:通过 provide / inject 实现跨层级组件通信。
- 策略模式(Strategy Pattern)
- 用途:compiler 和 patch 阶段,Vue 会根据不同平台(Web、SSR、Native)选择不同策略处理渲染。