vue中$on实现
在Vue中,$on是事件总线(Event Bus)模式的核心方法,用于监听自定义事件。以下是关于$on的实现和使用详解:
基本用法
$on方法用于监听一个自定义事件,接收两个参数:事件名称和回调函数。当事件被触发时,回调函数会执行。
// 创建事件总线(通常使用空的Vue实例)
const eventBus = new Vue();
// 监听事件
eventBus.$on('custom-event', (payload) => {
console.log('事件触发,参数:', payload);
});
实现原理
Vue的事件系统基于发布-订阅模式,内部通过_events对象存储事件监听器:
Vue.prototype.$on = function (event, fn) {
const vm = this;
// 如果event是数组,递归监听每个事件
if (Array.isArray(event)) {
for (let i = 0; i < event.length; i++) {
vm.$on(event[i], fn);
}
} else {
// 将回调函数存入_events对象
(vm._events[event] || (vm._events[event] = [])).push(fn);
}
return vm;
};
实际应用场景
组件间通信
父子组件通过事件总线通信,避免多层$emit传递:
// 父组件
mounted() {
eventBus.$on('child-event', this.handleChildEvent);
}
// 子组件
methods: {
triggerEvent() {
eventBus.$emit('child-event', { data: 123 });
}
}
全局状态通知 跨组件触发全局状态变化:
// A组件
eventBus.$on('user-login', this.refreshData);
// B组件(登录成功后)
eventBus.$emit('user-login', { user: newUser });
注意事项
事件监听会导致内存泄漏,需要在组件销毁时移除监听:
beforeDestroy() {
eventBus.$off('custom-event', this.eventHandler);
}
对于Vue 3,推荐使用mitt等第三方库替代事件总线,因为Vue 3移除了$onAPI:
import mitt from 'mitt';
const emitter = mitt();
emitter.on('event', () => { /*...*/ });
性能优化
避免在高频事件(如滚动)中使用$on,频繁触发会导致性能问题。这种情况下建议使用防抖/节流:
eventBus.$on('scroll', _.throttle(this.handleScroll, 200));
以上内容涵盖了$on的核心实现、典型用法和注意事项,可根据实际需求选择适合的应用方式。







