Vue3 uses Mitt central event bus to realize communication between components (publish subscription library)

foreword

The current project has been slowly upgraded from Vue2 to Vue3. The central event bus that came with Vue2 before was EventBus, which has been removed in Vue3. The official recommendation is to use the Mitt publish-subscribe library. Here is a brief record of how Mitt is used.

1. Import dependencies

npm i mitt -D

2. Global introduction

(1)/src/main.ts

// 引入Mitt工具并配置为全局方法
import mitt from 'mitt'
app.config.globalProperties.$mittBus = mitt()

3. Example code

(1)/src/views/Example/Mitt/index.vue

<template>
  <div class="mitt">
    <h1>
      <span>主页面</span>
      <p><button @click="handleRemoveAEvent">取消订阅A事件</button></p>
      <p><button @click="handleRemoveBEvent">取消订阅B事件</button></p>
      <p><button @click="handleEmitCEvent">发布C事件</button></p>
      <p><button @click="handleRemoveAllEvent">取消订阅所有事件</button></p>
    </h1>

    <div class="mitt-box">
      <emitA class="mitt-box_A" />
      <emitB class="mitt-box_B" />
    </div>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, getCurrentInstance } from 'vue'
import emitA from './emit_A.vue'
import emitB from './emit_B.vue'

// 代理对象
const { proxy } = getCurrentInstance()

// 消息事件总线
const bus = proxy.$mittBus

// 取消订阅A事件
const handleRemoveAEvent = async () => {
  proxy.$mittBus.off('A_Event')
  console.log('取消订阅A事件 Finished!')
}

// 取消订阅B事件
const handleRemoveBEvent = () => {
  proxy.$mittBus.off('B_Event')
  console.log('取消订阅B事件 Finished!')
}

// 取消订阅所有事件
const handleRemoveAllEvent = () => {
  proxy.$mittBus.all.clear()
  console.log('取消订阅所有事件 Finished!')
}

// 发布C事件
const handleEmitCEvent = () => {
  bus.emit('C_Event', '这是一条来自主页面发布的消息')
}

onMounted(() => {
  // 订阅A事件
  proxy.$mittBus.on('A_Event', (val) => {
    console.log('主页面收到一条信息 =>', val)
  })

  // 订阅B事件
  proxy.$mittBus.on('B_Event', (val) => {
    console.log('主页面收到一条信息 =>', val)
  })
})

onUnmounted(() => {
  handleRemoveAllEvent()
})
</script>

<style lang="less" scoped>
  .mitt {
    display: flex;
    flex-direction: column;
    padding: 100px;

    h1 {
      padding: 20px;
      border: 1px solid #dcdfe6;
      font-weight: lighter;
      text-align: center;
    }

    .mitt-box {
      flex: 1;
      display: flex;
      flex-direction: row;

      .mitt-box_A {
        flex: 1;
        border: 1px solid #dcdfe6;
        text-align: center;
        margin: 7px 3.5px 0 0;
        padding: 20px;
      }

      .mitt-box_B {
        flex: 1;
        border: 1px solid #dcdfe6;
        text-align: center;
        margin: 7px 0 0 3.5px;
        padding: 20px;
      }
    }
  }
</style>

(2)/src/views/Example/Mitt/emit_A.vue

<template>
  <div>
    <h1 style="font-weight: lighter">
      <span>A页面</span>
    </h1>
    <button @click="fn">发布A事件</button>
  </div>
</template>

<script>
export default {
  data: () => ({

  }),
  created() {

  },
  mounted() {
    this.fn()

    // 订阅C事件
    this.$mittBus.on('C_Event', (val) => {
      console.log('A页面收到一条信息 =>', val)
    })
  },
  methods: {
    fn() {
      // 发布A事件
      const bus = this.$mittBus
      const data = {
        success: true,
        data: 'OK',
        msg: '这是来自A页面的一条信息'
      }
      bus.emit('A_Event', data)
    }
  }
}
</script>

(3)/src/views/Example/Mitt/emit_B.vue

<template>
  <div>
    <h1 style="font-weight: lighter">
      <span>B页面</span>
    </h1>
    <button @click="fn">发布B事件</button>
  </div>
</template>

<script>
export default {
  data: () => ({

  }),
  created() {

  },
  mounted() {
    this.fn()

    // 订阅C事件
    this.$mittBus.on('C_Event', (val) => {
      console.log('B页面收到一条信息 =>', val)
    })
  },
  methods: {
    fn() {
      // 发布B事件
      const bus = this.$mittBus
      const data = {
        success: true,
        data: 'OK',
        msg: '这是来自B页面的一条信息'
      }
      bus.emit('B_Event', data)
    }
  }
}
</script>

4. Operation effect

Guess you like

Origin blog.csdn.net/Cai181191/article/details/132089381