EventBus核心方法用法

文章目录

Bus.on、Bus.emit、Bus.off 这三个是事件总线(EventBus) 的核心方法,专门用来解决跨组件/跨页面/跨模块通信(比如兄弟组件传值、无关联模块互相通知),是前端(Vue/React/小程序等)最常用的简易通信方案。

先记核心口诀:

  • Bus.on监听/订阅事件(等着别人发通知)
  • Bus.emit触发/发布事件(给别人发通知)
  • Bus.off取消监听(不再接收通知,防止内存泄漏)

一、先创建事件总线实例

所有用法都基于一个全局唯一的 Bus 实例,以 Vue 为例(原生JS/小程序/React 用法完全一致):

javascript 复制代码
// utils/bus.js (单独创建一个文件)
import Vue from 'vue'
// 导出一个空的 Vue 实例作为事件总线
export default new Vue()

二、逐行讲解用法

1. Bus.on(eventName, callback):监听事件

作用:监听一个自定义事件,别人触发这个事件时,你这里的回调函数就会执行。

参数

  • eventName:事件名(字符串,自定义,如 'updateData'
  • callback:触发时执行的函数

用法示例

javascript 复制代码
import Bus from '@/utils/bus'

// 监听 "message" 事件
Bus.on('message', (data) => {
  // data 就是 emit 传递过来的数据
  console.log('收到消息:', data)
})

2. Bus.emit(eventName, ...args):触发事件

作用 :主动发布/触发一个事件,所有监听了这个事件的地方都会收到通知。

参数

  • eventName:和 on 对应的事件名
  • ...args:要传递的数据(可以传多个参数)

用法示例

javascript 复制代码
import Bus from '@/utils/bus'

// 触发 "message" 事件,并传递数据
Bus.emit('message', { name: '小明', text: '你好' })

👉 执行后 :上面 Bus.on('message') 的回调会立刻执行,并拿到传递的对象。


3. Bus.off(eventName, callback):取消监听

作用 :销毁事件监听,必须用 ,否则会造成重复触发、内存泄漏

两种常用用法

  1. 取消指定事件+指定回调(最标准)
  2. 取消该事件所有监听
javascript 复制代码
import Bus from '@/utils/bus'

// 1. 先定义回调函数(必须用同一个函数引用,off 才能精准取消)
const handleMessage = (data) => { console.log(data) }

// 监听
Bus.on('message', handleMessage)

// 2. 取消指定监听(推荐)
Bus.off('message', handleMessage)

// 3. 取消该事件的所有监听
Bus.off('message')

三、完整实战示例(两个组件通信)

组件 A(发送方:emit)

vue 复制代码
<template>
  <button @click="sendMsg">发送消息给B组件</button>
</template>

<script>
import Bus from '@/utils/bus'
export default {
  methods: {
    sendMsg() {
      // 触发事件,传数据
      Bus.emit('toB', '来自A组件的消息')
    }
  }
}
</script>

组件 B(接收方:on + off)

vue 复制代码
<script>
import Bus from '@/utils/bus'
export default {
  created() {
    // 1. 监听事件
    Bus.on('toB', this.getMsg)
  },
  methods: {
    getMsg(data) {
      console.log('B组件收到:', data)
    }
  },
  beforeDestroy() {
    // 2. 组件销毁时取消监听!!!关键
    Bus.off('toB', this.getMsg)
  }
}
</script>

四、高频注意事项(必看)

  1. 事件名必须完全一致(大小写敏感)
  2. 回调函数必须是同一个引用
    不要写匿名函数:Bus.on('msg', ()=>{}),否则 Bus.off 无法取消,会造成重复触发!
  3. 必须在组件销毁时 off
    页面切换/组件销毁时一定要取消监听,否则事件会越来越多,导致卡顿、重复执行。
  4. 可以一对多:一个 emit,多个 on 都能收到。

五、极简原生JS版(不依赖框架)

如果不用 Vue,用原生 JS 手写简易 Bus,逻辑完全一样:

javascript 复制代码
class Bus {
  constructor() {
    this.events = {} // 存储事件
  }
  // 监听
  on(name, fn) {
    this.events[name] = this.events[name] || []
    this.events[name].push(fn)
  }
  // 触发
  emit(name, ...args) {
    this.events[name]?.forEach(fn => fn(...args))
  }
  // 取消
  off(name, fn) {
    if(!this.events[name]) return
    this.events[name] = this.events[name].filter(f => f !== fn)
  }
}
// 导出实例
export default new Bus()

用法和上面完全相同


六、知识总结

  1. Bus.on:监听事件,准备接收数据
  2. Bus.emit:触发事件,发送数据
  3. Bus.off:取消监听,防止bug
  4. 固定流程:on 监听 → emit 触发 → off 销毁
  5. 核心用途:无关联模块之间通信
相关推荐
川冰ICE26 分钟前
JavaScript进阶③|Map_Set_WeakMap_WeakSet,新型数据结构
开发语言·javascript·数据结构
小雨下雨的雨29 分钟前
鸿蒙PC用Electron框架 实现 房产交易系统核心算法深度解析
前端·javascript·算法·华为·electron·鸿蒙系统
吹个口哨写代码35 分钟前
IIS 部署 Vue/React 单页应用 (SPA) 刷新页面 404/403.18 报错原因及终极解决方案
前端·vue.js·react.js
LongJ_Sir37 分钟前
Cesium-浅水方程的简单实现
javascript
丷丩44 分钟前
MapLibre GL JS第36课:一个Source配置多个图层样式
javascript·gis·map·mapbox·maplibre gl js
老毛肚1 小时前
jeecgboot vue Pinia 拆分01
前端·javascript·vue.js
梦想的颜色9 小时前
TypeScript 完全指南(下):从类型体操到生产级配置
前端·javascript·typescript
888CC++12 小时前
如何在 C 语言中进行程序调试?
前端·javascript·算法
kyriewen14 小时前
我招了一个“Prompt工程师”来写前端,结果项目差点崩了
前端·javascript·面试
小新11014 小时前
从零开始 Vue.js
前端·javascript·vue.js