vue3 随手笔记10--组件通信方式9/3--全局事件总线(mitt)

发布于:2025-07-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

在 Vue 3 的 Composition API 和 <script setup> 中,$on、$off、$once 等方法已被废弃,所以不能再使用 Vue 实例直接作为事件总线。

 此文介绍的是使用mitt(轻量级第三方库)

 mitt是什么

mitt 是一个轻量级的 JavaScript 事件总线(Event Bus)库,常用于在组件之间或模块之间进行 跨层级通信。它非常适合在 Vue、React 或其他前端框架中实现全局事件管理。

如何使用

准备工作

demo 继续使用笔记8中的 链接为demo

在views文件夹下 创建新的文件夹为eventbus

在eventbus文件夹下

创建文件Parent.vue

<template>
    <div class="props-text">
        <h1>Global Event Bus 全局事件总线</h1>
        <h1>我是父组件</h1>
       
    </div>
</template>
<script setup>
 
</script>
 
 
 
<style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>

添加路由

import {createRouter , createWebHistory} from 'vue-router'
const routes = [
   {
    path: '/',
    name: 'index',
    component: () => import('@/views/index.vue')
   },
    {
        path: '/props',
        name: 'props',
        component: () => import('@/views/props/Parent.vue')
    },
    {
        path: '/customevent',
        name: 'customevent',
        component: () => import('@/views/customevent/Parent.vue')
    },
    {
        path: '/eventbus',
        name: 'eventbus',
        component: () => import('@/views/eventbus/Parent.vue')
    },
   
]

const router = createRouter({
    history: createWebHistory(),
    routes
})
export default router

app.vue中添加导航

<script setup>

</script>

<template>
<div class="com">
    <h1>
      各种Vue组件间通信/传值
    
    </h1>

    <div>
      <h2 style="display: inline">演示:</h2>&nbsp;&nbsp;
      <router-link to="/">index</router-link>&nbsp;&nbsp;
      <router-link to="/props">props</router-link>&nbsp;&nbsp;
      <router-link to="/customevent">custom event</router-link>&nbsp;&nbsp;
      <router-link to="/eventbus">event bus</router-link>&nbsp;&nbsp;
     
    </div>
    <br>
    <router-view></router-view>
  </div>
</template>


<style  scoped>
  .com {
    margin: 10px;
    
  }
  
</style>
<style>
  .box {
    border: solid 1px #aaa;
    margin: 5px;
    padding: 5px;
  }
</style>

 分别创建子组件1  和 子组件2  用于子组件之间的数据传递

Child1.vue

<template>
    <div class="son">
        <h1>我是子组件1</h1>
        <p>{{ msg }}</p>
    </div>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('');
</script>



<style scoped>
.son {
width: 100px;
height: 100px;
background-color: red;
}
</style>

Child2.vue

<template>
    <div class="son">
        <h1>我是子组件2</h1>
      <button @click="handler">点击我给子组件1传递</button>
    </div>
</template>
<script setup>


const handler = () => {
   
}
</script>



<style scoped>
.son {
width: 100px;
height: 100px;
background-color: green;
}
</style>

父组件中 引用两个子组件

<template>
    <div class="props-text">
        <h1>全局事件总线Global Event Bus</h1>
        <h1>我是父组件</h1>
      
       <Child1></Child1>
       <Child2></Child2>
    </div>
</template>
<script setup>
import Child1 from './Child1.vue';
import Child2 from './Child2.vue';
</script>



<style scoped>
.props-text {
width: 400px;
height: 400px;
background-color: burlywood;
}
</style>

安装mitt

npm install mitt

基本使用mitt

在src文件夹 创新文件夹bus

bus 创建index.js


//引入mitt插件:mitt一个方法,方法执行会返回bus对象
import mitt from "mitt";
const $bus = mitt();
export default $bus;

开始组件中使用mitt

在子组件2中引用mitt

<template>
    <div class="son">
        <h1>我是子组件2</h1>
      <button @click="handler">点击我给子组件1传递</button>
    </div>
</template>
<script setup>
import $bus from '@/bus';

const handler = () => {
    $bus.emit('son1', {data:'子组件2给子组件1传递的数据'})
}
</script>



<style scoped>
.son {
width: 100px;
height: 100px;
background-color: green;
}
</style>

子组件1中 使用

<template>
    <div class="son">
        <h1>我是子组件1</h1>
        <p>{{ msg }}</p>
    </div>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('');
import $bus from '../../bus';
console.log($bus)
import { onMounted } from 'vue'
//组件挂载完毕的时候,当前组件绑定一个事件,接受将来兄弟组件传递的数据
//什么是 onMounted?
//当组件被渲染并插入到 DOM 中后,onMounted 会被调用。此时你可以安全地访问 DOM 元素、发起网络请求、初始化第三方库等。
onMounted(() => {
    console.log('组件已挂载')
  // 可以在这里执行初始化操作,例如:
  // - 获取数据
  // - 操作 DOM
  // - 初始化插件

  //第一个参数:即为事件类型 第二个参数:即为事件回调
    $bus.on('son1',(data) => {
        console.log(data)
        msg.value = data.data
        
    })
})
</script>



<style scoped>
.son {
width: 100px;
height: 100px;
background-color: red;
}
</style>

控制台输出为

总结 

支持的 API 方法

方法 说明
on(type, handler) 添加指定类型的事件监听器
off(type, handler) 移除指定类型的事件监听器
emit(type, [event]) 触发指定类型事件,并传递参数
all.clear() 移除所有事件的所有监听器

注意事项

  • 使用 mitt 时要小心内存泄漏问题,在组件卸载时记得移除监听器。
  • 在 Vue 中,也可以考虑使用 provide/inject 或者 Pinia/Vuex 状态管理替代 mitt,但 mitt 更加简单灵活。
  • 如果你在 <script setup> 中使用,可以用 onBeforeUnmount 来清理监听器:
<script setup>
import $bus from '../../bus';
import { onMounted, onBeforeUnmount } from 'vue'

const handler = (data) => {
  console.log('收到数据:', data)
}

onMounted(() => {
  $bus.on('son1', handler)
})

onBeforeUnmount(() => {
  $bus.off('son1', handler)
})
</script>

在 Vue 项目中的典型应用

适用于:

  • 跨组件通信(非父子组件)
  • 全局状态变化通知
  • 插件间通信
  • 解耦业务逻辑和 UI 层
特点 描述
体积小 几 KB,无依赖
使用简单 提供 .on.off.emit
可维护性强 适合中小型项目的事件通信
通用性高 可用于任何 JavaScript 项目


网站公告

今日签到

点亮在社区的每一天
去签到