最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3中的事件總線詳解

 更新時(shí)間:2026年01月12日 09:18:34   作者:csdn_HPL  
在Vue3中,推薦使用CompositionAPI和第三方庫mitt來實(shí)現(xiàn)事件總線,而不是Vue2中使用Vue實(shí)例的方式

在 Vue 3 中,由于創(chuàng)建 Vue 實(shí)例的方式發(fā)生了變化,并且推薦使用 Composition API,事件總線的實(shí)現(xiàn)方式也與 Vue 2 有所不同。

一、Vue 3 事件總線的核心變化

在 Vue 2 中,我們通常 new Vue() 來創(chuàng)建事件總線。但在 Vue 3 中:

  • Vue 構(gòu)造函數(shù)不再直接導(dǎo)出,取而代之的是 createApp
  • Vue 實(shí)例不再是一個(gè)事件發(fā)射器,它移除了 $on, $off, 和 $once 方法。

因此,我們不能再用 new Vue() 來創(chuàng)建事件總線。

二、Vue 3 實(shí)現(xiàn)事件總線的推薦方案

有幾種方式可以在 Vue 3 中實(shí)現(xiàn)事件總線模式,這里介紹最主流和推薦的兩種。

方案一:使用第三方庫mitt(最推薦)

mitt 是一個(gè)小巧(約 200 bytes)、功能完整的的事件總線庫,它不依賴 Vue,但可以完美地與 Vue 3 集成。這是目前 Vue 社區(qū)公認(rèn)的最佳實(shí)踐。

1. 安裝 mitt

npm install mitt

2. 創(chuàng)建事件總線

創(chuàng)建一個(gè)單獨(dú)的文件(如 event-bus.js):

// event-bus.js
import mitt from 'mitt';

// 創(chuàng)建一個(gè) mitt 實(shí)例并導(dǎo)出
const emitter = mitt();

export default emitter;

3. 在組件中使用

發(fā)布事件(發(fā)送消息):

使用 emitter.emit(eventType, data)

<!-- PublisherComponent.vue -->
<template>
  <button @click="sendMessage">發(fā)送消息</button>
</template>

<script setup>
import { ref } from 'vue';
import emitter from './event-bus.js'; // 導(dǎo)入事件總線

const message = ref('Hello from Vue 3!');

const sendMessage = () => {
  // 發(fā)布一個(gè)名為 'messageEvent' 的事件,并攜帶數(shù)據(jù)
  emitter.emit('messageEvent', message.value);
  // 也可以發(fā)布沒有數(shù)據(jù)的事件
  // emitter.emit('someNotification');
};
</script>

訂閱事件(接收消息):

使用 emitter.on(eventType, callback)

關(guān)鍵點(diǎn): 在 Composition API 的 setup 中,需要在 onMounted 生命周期中訂閱,并在 onUnmounted 中取消訂閱,以防止內(nèi)存泄漏。

<!-- SubscriberComponent.vue -->
<template>
  <div>收到消息: {{ receivedMessage }}</div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import emitter from './event-bus.js'; // 導(dǎo)入事件總線

const receivedMessage = ref('');

// 定義處理事件的函數(shù)
const handleMessage = (data) => {
  receivedMessage.value = data;
  console.log('收到數(shù)據(jù):', data);
};

// 組件掛載后訂閱事件
onMounted(() => {
  emitter.on('messageEvent', handleMessage);
});

// 組件卸載前取消訂閱
onUnmounted(() => {
  emitter.off('messageEvent', handleMessage);
});
</script>

mitt 的其他常用 API:

  • emitter.all: 一個(gè) Map,可以查看所有事件和處理函數(shù)。
  • emitter.off(eventType, handler): 移除特定事件的特定監(jiān)聽器。
  • emitter.emit(eventType): 觸發(fā)事件,可不傳數(shù)據(jù)。

方案二:使用provide/inject實(shí)現(xiàn)一個(gè)簡單的事件總線

如果你不想引入第三方庫,并且應(yīng)用場景比較簡單,可以利用 Vue 3 的 provideinject 特性,在根組件提供一個(gè)響應(yīng)式對(duì)象作為事件總線。

1. 在根組件(如 App.vue)提供事件總線

<!-- App.vue -->
<template>
  <PublisherComponent />
  <SubscriberComponent />
</template>

<script setup>
import { ref, provide } from 'vue';
import PublisherComponent from './components/PublisherComponent.vue';
import SubscriberComponent from './components/SubscriberComponent.vue';

// 1. 創(chuàng)建一個(gè)響應(yīng)式對(duì)象來存儲(chǔ)事件和監(jiān)聽器(簡化版)
const eventBus = ref({});

// 2. 創(chuàng)建事件總線的方法
const eventBusMethods = {
  $on(event, callback) {
    if (!eventBus.value[event]) {
      eventBus.value[event] = [];
    }
    eventBus.value[event].push(callback);
  },
  $emit(event, ...args) {
    if (eventBus.value[event]) {
      eventBus.value[event].forEach(callback => callback(...args));
    }
  },
  // 可以自行實(shí)現(xiàn) $off 等功能
};

// 3. 將事件總線方法提供給所有子組件
provide('eventBus', eventBusMethods);
</script>

2. 在子組件中注入并使用

發(fā)布者組件:

<!-- PublisherComponent.vue -->
<template>
  <button @click="$emitMessage">發(fā)送</button>
</template>

<script setup>
import { inject } from 'vue';

// 注入事件總線
const eventBus = inject('eventBus');

const $emitMessage = () => {
  eventBus.$emit('myEvent', '一些數(shù)據(jù)');
};
</script>

訂閱者組件:

<!-- SubscriberComponent.vue -->
<template>
  <div>消息: {{ message }}</div>
</template>

<script setup>
import { ref, inject, onMounted, onUnmounted } from 'vue';

// 注入事件總線
const eventBus = inject('eventBus');
const message = ref('');

const handleEvent = (data) => {
  message.value = data;
};

onMounted(() => {
  eventBus.$on('myEvent', handleEvent);
});

// 注意:這個(gè)簡易實(shí)現(xiàn)需要更復(fù)雜的邏輯來實(shí)現(xiàn) $off,這里省略了取消訂閱
// onUnmounted(() => { ... });
</script>

三、Vue 3 事件總線 vs. 狀態(tài)管理工具(如 Pinia)

特性事件總線(如 mitt)狀態(tài)管理(如 Pinia)
目的組件間通信,傳遞事件消息全局狀態(tài)管理,集中管理數(shù)據(jù)
數(shù)據(jù)流單向或雙向,通常是“一發(fā)一收”單向數(shù)據(jù)流,狀態(tài)可預(yù)測
數(shù)據(jù)持久性事件觸發(fā)后即消失,不存儲(chǔ)數(shù)據(jù)數(shù)據(jù)存儲(chǔ)在 Store 中,是持久的
適用場景簡單的、一次性的通知(如顯示通知、表單提交完成)復(fù)雜的、需要共享和持久化的數(shù)據(jù)(如用戶登錄信息、購物車)
調(diào)試相對(duì)困難,事件是匿名的非常方便,有 DevTools 支持

總結(jié)與建議

  • 對(duì)于 Vue 3,強(qiáng)烈推薦使用 mitt 來實(shí)現(xiàn)事件總線。它輕量、簡單且完美契合 Vue 3 的理念。
  • 將事件總線的創(chuàng)建邏輯放在一個(gè)獨(dú)立的模塊中(如 event-bus.js),便于管理和維護(hù)。
  • 務(wù)必記住在組件卸載時(shí)(onUnmounted)取消事件監(jiān)聽,這是避免內(nèi)存泄漏的關(guān)鍵。
  • 如果應(yīng)用的數(shù)據(jù)流變得非常復(fù)雜,需要多個(gè)組件共享和修改同一份數(shù)據(jù),請考慮使用 Pinia 這類專門的狀態(tài)管理庫,而不是濫用事件總線。事件總線更適合處理行為通知,而非管理狀態(tài)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳談Object.defineProperty 及實(shí)現(xiàn)數(shù)據(jù)雙向綁定

    詳談Object.defineProperty 及實(shí)現(xiàn)數(shù)據(jù)雙向綁定

    這篇文章主要介紹了詳談Object.defineProperty 及實(shí)現(xiàn)數(shù)據(jù)雙向綁定,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 如何利用Vue3+Element?Plus實(shí)現(xiàn)動(dòng)態(tài)標(biāo)簽頁及右鍵菜單

    如何利用Vue3+Element?Plus實(shí)現(xiàn)動(dòng)態(tài)標(biāo)簽頁及右鍵菜單

    標(biāo)簽頁一般配合菜單實(shí)現(xiàn),當(dāng)你點(diǎn)擊一級(jí)菜單或者二級(jí)菜單時(shí),可以增加對(duì)應(yīng)的標(biāo)簽頁,當(dāng)你點(diǎn)擊對(duì)應(yīng)的標(biāo)簽頁,可以觸發(fā)對(duì)應(yīng)的一級(jí)菜單或者二級(jí)菜單,下面這篇文章主要給大家介紹了關(guān)于如何利用Vue3+Element?Plus實(shí)現(xiàn)動(dòng)態(tài)標(biāo)簽頁及右鍵菜單的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Ant Design Vue resetFields表單重置不生效問題及解決

    Ant Design Vue resetFields表單重置不生效問題及解決

    這篇文章主要介紹了Ant Design Vue resetFields 表單重置不生效問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • vue3+elementUI如何動(dòng)態(tài)修改Loading中提示文字

    vue3+elementUI如何動(dòng)態(tài)修改Loading中提示文字

    這篇文章主要介紹了vue3+elementUI如何動(dòng)態(tài)修改Loading中提示文字的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 詳解Vue3中Teleport的使用

    詳解Vue3中Teleport的使用

    門戶(Portal)的概念是Vue3的新功能之一,也就是將模板 HTML 移至 DOM 的不同部分的方法。Portal 是 React 中的常見功能,Vue2 的 portal-vue &nbsp;庫也提供了相似的功能。在 Vue3 中用 Teleport 對(duì)這個(gè)概念提供了原生支持。本文將介紹Teleport的相關(guān)用法
    2021-05-05
  • vue中@click如何綁定多個(gè)事件

    vue中@click如何綁定多個(gè)事件

    這篇文章主要介紹了vue中@click如何綁定多個(gè)事件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 淺析Vue3中通過v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定

    淺析Vue3中通過v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定

    這篇文章主要介紹了淺析Vue3中通過v-model實(shí)現(xiàn)父子組件的雙向數(shù)據(jù)綁定及利用computed簡化父子組件雙向綁定,需要的朋友可以參考下
    2022-12-12
  • 解決vue3?defineProps?引入定義的接口報(bào)錯(cuò)

    解決vue3?defineProps?引入定義的接口報(bào)錯(cuò)

    這篇文章主要為大家介紹了解決vue3?defineProps?引入定義的接口報(bào)錯(cuò)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 前端Vue通過Minio返回的URL下載文件實(shí)現(xiàn)方法

    前端Vue通過Minio返回的URL下載文件實(shí)現(xiàn)方法

    Minio是一個(gè)靈活、高性能、開源的對(duì)象存儲(chǔ)解決方案,適用于各種存儲(chǔ)需求,并可以與云計(jì)算、容器化、大數(shù)據(jù)和應(yīng)用程序集成,這篇文章主要給大家介紹了關(guān)于前端Vue通過Minio返回的URL下載文件實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • 如何快速上手Vuex

    如何快速上手Vuex

    本文主要介紹了Javascript中Vuex的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02

最新評(píng)論

德昌县| 当阳市| 杭州市| 甘德县| 龙陵县| 大同市| 朔州市| 万宁市| 金坛市| 监利县| 贵港市| 佛冈县| 渝北区| 渭南市| 长治县| 台中县| 武威市| 苏尼特左旗| 吴桥县| 武清区| 堆龙德庆县| 海口市| 襄樊市| 石家庄市| 延吉市| 潜山县| 鄱阳县| 通化县| 邢台县| 兴义市| 博兴县| 会东县| 无锡市| 同德县| 建宁县| 孟连| 陇南市| 乐清市| 化德县| 铜梁县| 乐东|