【Vue3】组件通信之mitt

【Vue3】组件通信之mitt

背景

随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。

简介

本文介绍 Vue3 中如何使用 mitt 实现任意组件间传数据。

Vue3 推荐使用 Mitt 作为事件总线(EventBus)实现平行组件间传数据。

Vue3 中组件间通信包括:

  • 父组件向子组件传数据,实现方案有:
    • props
    • v-model
    • $ref
    • 默认插槽 / 具名插槽
  • 子组件向父组件传数据
    • props
    • v-model
    • $parent
    • 自定义事件
    • 作用域插槽
  • 父组件向子组件的子组件传数据,即向孙子组件传数据
    • $attrs
    • provider & inject
  • 任意组件间传数据
    • mitt
    • Pinia

开发环境

分类 名称 版本
操作系统 Windows Windows 11
IDE Visual Studio Code 1.91.1

开发步骤及源码

1> 创建 Vue3 工程,参考:【Vue3】工程创建及目录说明。

2> 执行 npm i mitt 命令安装 mitt。

复制代码
PS D:\...> npm i mitt

added 1 package in 1s

10 packages are looking for funding
  run `npm fund` for details

3> 在 src 下新建 tools / utils 工具文件夹,在其中新建 emitter.ts。

复制代码
// 引入mitt
import mitt from 'mitt'
// 调用mitt得到emitter,emitter可以订阅事件及发布事件
const emitter = mitt()
// 暴露emitter
export default emitter

4> 修改 src 目录下 main.ts,引入 emitter。

复制代码
import { createApp } from 'vue'
import App from './App.vue'
import emitter from './tools/emitter'

createApp(App).mount('#app')

5> 删除 src 目录下 assets 和 components 目录中内容。

6> 在 src/components 新建订阅事件的组件。

复制代码
<template>
    <div class="media">
        <h2>Breaking News:</h2>
        <ul>
            <li v-for="item in news" :key="item.time">{{ item.time }} : {{ item.title }}</li>
        </ul>
    </div>
</template>

<script setup lang="ts">
import { onUnmounted, reactive } from 'vue'
import emitter from '@/tools/emitter'

const news = reactive<any>([])

emitter.on('news', (value) => {
    news.push(value)
})

// 组件卸载时需要主动解绑事件
onUnmounted(() => {
    emitter.off('news')
})
</script>

<style scoped lang="scss">
.media {
    background-color: coral;
    height: 600px;
    padding: 10px;
}
</style>

注意:需要执行 npm install -D sass 命令安装 CSS 预处理器。

7> 在 src/components 新建发布事件的组件。

复制代码
<template>
    <div class="reporter">
        <h2>Reporter</h2>
        <button @click="report">报道新闻</button>
    </div>
</template>

<script setup lang="ts">
import emitter from '@/tools/emitter'

function report() {
    emitter.emit('news', {
        title: 'Breaking news...',
        time: getDateTime(),
    })
}

function getDateTime() {
    const dateTime = new Date()
    return dateTime.getFullYear() 
        + '/' + (dateTime.getMonth() + 1)
        + '/' + dateTime.getDate()
        + ' ' + dateTime.getHours()
        + ':' + dateTime.getMinutes()
        + ':' + dateTime.getSeconds()
}
</script>

<style scoped lang="scss">
.reporter {
    background-color: darkcyan;
    padding: 10px;
    button {
        font-size: 18px;
        font-weight: bold;
        height: 30px;
        width: 120px;
    }
}
</style>

8> 修改 Vue 根组件 src/App.vue 作为最顶层组件,引入以上两个组件。

复制代码
<template>
  <div class="content">
    <div class="component"><Media /></div>
    <div class="component"><Reporter /></div>
  </div>
</template>

<script setup lang="ts">
import Media from './components/Media.vue'
import Reporter from './components/Reporter.vue'
</script>

<style scoped lang="scss">
.content {
  background-color: darkgray;
  padding: 20px;
  display: flex;
  .component {
    width: 500px;
    margin-right: 30px;
  }
}
</style>

9> 执行命令 npm run dev 启动应用,浏览器访问:http://localhost:5173/,每点击一次 Reporter 组件中的 报道新闻 按钮,Media 组件便会接收并显示。

总结

  • Mitt 是一个事件总线(EventBus),可用于平行组件间传数据;
  • 接收数据方使用 emitter.on 方法订阅事件,待事件发生时接收对应数据;
  • 接收数据方在卸载时需要主动调用 emitter.off 方法取消事件订阅;
  • 发送数据方使用 emitter.emit 方法发布事件。
相关推荐
冒险的豆子14 小时前
Vue2 、Vue3 响应式对比及优劣
vue
RuoyiOffice18 小时前
SpringBoot3+Vue3 员工全生命周期:入转调离如何衔接账号、权限、资产与交接
spring boot·vue3·权限管理·员工管理·hrm·ruoyi office·人事变更
NetX行者1 天前
用 Vite + Vue3 + UnoCSS 搭建企业级项目模板(一):基础骨架
vue·vite·unocss
java水泥工2 天前
什么是前端
java·vue·html5
RuoyiOffice2 天前
SpringBoot3+Vue3 企业 AI 工作流:Tinyflow 画布、LLM 节点与在线试跑怎么落地
spring boot·大模型·vue3·agent·ai工作流·ruoyi office·tinyflow
RuoyiOffice2 天前
Springboot + Vue3 + FormCreate表单引擎,直接用AI对话进行单据设计,告别拖拽画表单
spring boot·低代码·vue3·sse·formcreate·ruoyi office·ai表单
mont evergreen3 天前
一封从外部世界寄来的信:二维码数据如何穿越三重门,抵达你的屏幕
electron·vue·事件
志尊宝3 天前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
怦然丶心动4 天前
用 Java 把干支历法算清楚:从节气切年到可读摘要
java·算法·vue·独立开发·spring boot / spring
RuoyiOffice5 天前
SpringBoot+Vue3+Onlyoffice 企业文件生命周期:上传、业务关联、权限、版本与安全清理
spring boot·vue3·文件管理·对象存储·权限控制·ruoyi office·附件管理