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

Vue3中的事件總線詳解

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

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

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

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

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

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

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

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

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

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

1. 安裝 mitt

npm install mitt

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

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

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

// 創(chuàng)建一個 mitt 實例并導出
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'; // 導入事件總線

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

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

訂閱事件(接收消息):

使用 emitter.on(eventType, callback)

關(guā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'; // 導入事件總線

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

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

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

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)建一個響應式對象來存儲事件和監(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));
    }
  },
  // 可以自行實現(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);
});

// 注意:這個簡易實現(xiàn)需要更復雜的邏輯來實現(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)可預測
數(shù)據(jù)持久性事件觸發(fā)后即消失,不存儲數(shù)據(jù)數(shù)據(jù)存儲在 Store 中,是持久的
適用場景簡單的、一次性的通知(如顯示通知、表單提交完成)復雜的、需要共享和持久化的數(shù)據(jù)(如用戶登錄信息、購物車)
調(diào)試相對困難,事件是匿名的非常方便,有 DevTools 支持

總結(jié)與建議

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

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

相關(guān)文章

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

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

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

    如何利用Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁及右鍵菜單

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

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

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

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

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

    詳解Vue3中Teleport的使用

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

    vue中@click如何綁定多個事件

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

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

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

    解決vue3?defineProps?引入定義的接口報錯

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

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

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

    如何快速上手Vuex

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

最新評論

襄城县| 酉阳| 开原市| 新龙县| 盐源县| 贡觉县| 雅安市| 天峻县| 加查县| 介休市| 永和县| 乌拉特后旗| 隆尧县| 来凤县| 探索| 罗平县| 淮北市| 庆城县| 天台县| 洪江市| 剑川县| 绩溪县| 翁牛特旗| 安宁市| 右玉县| 江北区| 自贡市| 宣化县| 鱼台县| 稻城县| 航空| 普兰店市| 前郭尔| 饶阳县| 罗源县| 武城县| 南康市| 佛坪县| 林州市| 香格里拉县| 昌乐县|