vue实现发布订阅模式
发布订阅模式简介
发布订阅模式(Pub/Sub)是一种消息通信范式,发布者(Publisher)不直接发送消息给订阅者(Subscriber),而是通过事件中心(Event Channel)进行中转。Vue 本身通过 $emit 和 $on 提供了简单的实现,但可以进一步扩展为更通用的方案。
基于 Vue 的简单实现
Vue 实例本身可作为事件中心,利用 $emit 和 $on 实现基础的发布订阅:
// 创建事件中心
const eventBus = new Vue();
// 订阅事件
eventBus.$on('event-name', (payload) => {
console.log('收到消息:', payload);
});
// 发布事件
eventBus.$emit('event-name', { data: 'test' });
独立事件中心类
若需脱离 Vue 实例,可封装一个独立的 EventBus 类:
class EventBus {
constructor() {
this.events = {};
}
// 订阅
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
// 发布
emit(event, ...args) {
const callbacks = this.events[event];
if (callbacks) {
callbacks.forEach(cb => cb(...args));
}
}
// 取消订阅
off(event, callback) {
const callbacks = this.events[event];
if (callbacks) {
this.events[event] = callbacks.filter(cb => cb !== callback);
}
}
}
// 使用示例
const bus = new EventBus();
bus.on('update', data => console.log(data));
bus.emit('update', '新数据');
结合 Vue 的 provide/inject
在 Vue 应用中,可通过 provide 和 inject 共享事件总线:
// 父组件提供事件总线
const EventBus = new Vue();
export default {
provide() {
return { eventBus: EventBus };
}
};
// 子组件注入并使用
export default {
inject: ['eventBus'],
mounted() {
this.eventBus.$on('event', this.handleEvent);
},
methods: {
handleEvent(payload) { /* ... */ }
}
};
注意事项
- 内存泄漏:组件销毁时需通过
$off清理订阅。 - 命名冲突:事件名建议使用命名空间(如
user:updated)。 - 性能:高频事件需考虑防抖或节流。
替代方案
- Vuex:适合全局状态管理,但复杂度较高。
- 第三方库:如
mitt或tiny-emitter,提供更轻量的实现。







