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)選擇不同策略處理渲染。