Vue3 数据总线的实现

 更新时间:2026年04月05日 09:29:01   作者:幻象黑兔  
在Vue3中,可以使用mitt实现事件总线,mitt是一个轻量级的事件发布/订阅库,核心功能包括发布事件、订阅事件和取消订阅,下面就来介绍一下如何使用,感兴趣的可以了解一下

在 Vue 开发中,组件通信 是一个非常重要的主题。对于父子组件之间的通信,我们可以通过 props/emit 来实现。然而,在 非父子组件 或 兄弟组件 之间进行通信时,传统的 props/emit 就显得力不从心了。这时,事件总线(Event Bus) 就派上了用场。

在 Vue 2 中,我们可以通过 new Vue() 创建一个事件总线实例,并使用 $emit$on$off 来实现事件的发布与订阅。然而,在 Vue 3 中,这些 API 被移除了。幸运的是,我们可以借助一个轻量级的开源库 —— mitt 来实现类似的功能。

什么是mitt?

mitt 是一个极简的JavaScript事件发布/订阅库,体积仅有200字节左右,但却功能强大。它可以在任何 JavaScript 环境中使用,包括 Vue、React 甚至原生 JS。mitt 的核心功能非常简单:

  • 发布事件:通过 emit 方法触发事件。
  • 订阅事件:通过 on 方法监听事件。
  • 取消订阅:通过 off 方法移除事件监听器。

如何在 Vue 3 中使用mitt?

1、安装mitt

首先,我们需要通过 npm 安装 mitt

npm i mitt

2、创建事件总线

接下来,我们创建一个事件总线实例

import mitt from "mitt";

const emitter = mitt();
export default emitter;

3、在组件中订阅事件

<template>
  <div>
    <div>Bar: {{ date }}</div>
  </div>
</template>
<script setup lang="ts">
import { onBeforeMount, onMounted, ref } from 'vue';
import emitter from './emitter';

const date = ref()
onMounted(() => {
  emitter.on('bar', (data) => {
    date.value = data
  })
})

onBeforeMount(() => {
  emitter.off('bar')
})
</script>

4、在组件中发布事件

// Foo.vue
<template>
  <div>
    <span>Foo: </span>
    <button @click="click">触发事件</button>
  </div>
</template>
<script setup lang="ts">
import emitter from './emitter';

function click() {
  emitter.emit('bar', new Date().toLocaleString());
}
</script>

mitt实现原理

miit的原理其实非常简单,主要依赖于一个 Map 对象来存储事件类型及其对应的处理函数。以下是mitt的简化实现:

function mitt() {
    const all = new Map();
    return {
        // 订阅事件
        on(type, handler) {
            const handlers = all.get(type)
            if (handlers) {
                handlers.push(handler)
            } else {
                all.set(type, [handler])
            }
        },
        // 取消订阅
        off(type, handler) {
            const handlers = all.get(type)
            if (!handlers) {
                return
            }
            if (handler) {
                const index = handlers.indexOf(handler)
                if (index > -1) {
                    handlers.splice(index, 1)
                }
            } else {
                all.set(type, [])
            }
        },
        // 发布事件
        emit(type, ...args) {
            const handlers = all.get(type);
            handlers?.slice().map(handler => {
                handler(...args)
            })
        }
    }
}

到此这篇关于Vue3 数据总线的实现的文章就介绍到这了,更多相关Vue3 数据总线内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决Element组件的坑:抽屉drawer和弹窗dialog

    解决Element组件的坑:抽屉drawer和弹窗dialog

    这篇文章主要介绍了解决Element组件的坑:抽屉drawer和弹窗dialog问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Vue Element前端应用开发之常规的JS处理函数

    Vue Element前端应用开发之常规的JS处理函数

    在我们使用Vue Element处理界面的时候,往往碰到需要利用JS集合处理的各种方法,如Filter、Map、reduce等方法,也可以涉及到一些对象属性赋值等常规的处理或者递归的处理方法,本篇随笔列出一些在VUE+Element 前端开发中经常碰到的JS处理场景,供参考学习。
    2021-05-05
  • vue3如何监听页面的滚动

    vue3如何监听页面的滚动

    这篇文章主要给大家介绍了关于vue3如何监听页面的滚动的相关资料,在vue中实现滚动监听和原生js无太大差异,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-07-07
  • 解读Vue实例的属性及模板渲染

    解读Vue实例的属性及模板渲染

    这篇文章主要介绍了解读Vue实例的属性及模板渲染问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Vue Promise的axios请求封装详解

    Vue Promise的axios请求封装详解

    这篇文章主要介绍了Vue Promise的axios请求封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • vue3父子组件传值中props使用细节浅析

    vue3父子组件传值中props使用细节浅析

    这篇文章主要给大家介绍了关于vue3父子组件传值中props使用细节的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • Vue混入mixins滚动触底的方法

    Vue混入mixins滚动触底的方法

    这篇文章主要介绍了Vue混入mixins滚动触底的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 在vue中如何引入外部的css文件

    在vue中如何引入外部的css文件

    这篇文章主要介绍了在vue中如何引入外部的css文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue router自动判断左右翻页转场动画效果

    vue router自动判断左右翻页转场动画效果

    最近公司项目比较少终于有空来记录一下自己对vue-router的一些小小的使用心得,本文给大家分享vue router自动判断左右翻页转场动画效果,感兴趣的朋友一起看看吧
    2017-10-10
  • vue之带参数跳转打开新页面、新窗口

    vue之带参数跳转打开新页面、新窗口

    这篇文章主要介绍了vue之带参数跳转打开新页面、新窗口方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论