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

Vue3中自定義事件總線的實(shí)現(xiàn)代碼

 更新時(shí)間:2024年05月28日 08:58:54   作者:BestAns  
隨著 Vue 3 的發(fā)布,一些在 Vue 2 中常用的通信方式在 Vue 3 中可能不再適用或有所變化,為了應(yīng)對(duì)這種變化,我們可以選擇在 Vue 3 應(yīng)用中實(shí)現(xiàn)自定義的“事件總線”機(jī)制,所以本文給大家介紹了Vue3中如何自定義消息總線,需要的朋友可以參考下

前言

Vue 開(kāi)發(fā)中,組件之間的通信是一個(gè)常見(jiàn)的需求,無(wú)論是父組件向子組件傳遞數(shù)據(jù),還是子組件向父組件傳遞數(shù)據(jù),甚至是兄弟組件之間的數(shù)據(jù)交換。這些通信需求在構(gòu)建復(fù)雜的 Vue 應(yīng)用時(shí)尤為關(guān)鍵。

Vue 提供了多種組件通信的方式,如 props 用于父組件向子組件傳遞數(shù)據(jù),emit 用于子組件觸發(fā)事件并傳遞數(shù)據(jù)給父組件,vuex 適用于狀態(tài)管理場(chǎng)景,而 provide/inject 則提供了依賴注入的方式。在 Vue 2 中,還有 eventBus$attrs/$listeners 以及 $parent/children 等方法來(lái)輔助組件間的通信。

然而,隨著 Vue 3 的發(fā)布,一些在 Vue 2 中常用的通信方式在 Vue 3 中可能不再適用或有所變化。為了應(yīng)對(duì)這種變化,我們可以選擇在 Vue 3 應(yīng)用中實(shí)現(xiàn)自定義的“事件總線”機(jī)制。這種機(jī)制通常是將一個(gè)事件中心(或稱為事件總線)掛載到Vue的全局對(duì)象上,從而使得任何組件都可以方便地通過(guò)事件總線來(lái)發(fā)布或監(jiān)聽(tīng)事件。

通過(guò)使用這樣的自定義事件總線,開(kāi)發(fā)者可以在 Vue 3 應(yīng)用中實(shí)現(xiàn)靈活的組件間通信,無(wú)論這些組件之間的層級(jí)關(guān)系如何,都能輕松地實(shí)現(xiàn)數(shù)據(jù)和事件的傳遞。

發(fā)布-訂閱模式

發(fā)布-訂閱模式(Publish-Subscribe Pattern)是一種在軟件設(shè)計(jì)中常見(jiàn)的模式,它允許消息發(fā)送者和接收者之間通過(guò)事件進(jìn)行通信,而不必直接相互依賴。這種模式的主要思想是通過(guò)一個(gè)被稱為“消息中心”或“事件總線”的實(shí)體來(lái)協(xié)調(diào)消息的發(fā)布和訂閱。

一個(gè)完整的發(fā)布-訂閱模式通常包含以下幾個(gè)部分:

  • 發(fā)布者(Publisher):負(fù)責(zé)向消息中心發(fā)布事件或消息的對(duì)象。發(fā)布者通常不關(guān)心誰(shuí)訂閱了這些事件,只負(fù)責(zé)在特定情況下觸發(fā)它們。
  • 訂閱者(Subscriber):對(duì)特定事件感興趣的對(duì)象,它們會(huì)向消息中心訂閱這些事件。當(dāng)發(fā)布者發(fā)布一個(gè)事件時(shí),所有訂閱了該事件的訂閱者都會(huì)收到通知。
  • 消息中心(Event Bus/Message Center):負(fù)責(zé)管理事件的發(fā)布、訂閱和通知的對(duì)象。它存儲(chǔ)了事件和訂閱者之間的關(guān)系,并在事件被發(fā)布時(shí),將事件通知給所有訂閱了該事件的訂閱者。

發(fā)布-訂閱模式的優(yōu)點(diǎn)包括:

  • 解耦性:發(fā)布者和訂閱者之間不存在直接的依賴關(guān)系,這使得它們可以獨(dú)立地變化,而不需要修改對(duì)方。這種解耦性提高了代碼的可維護(hù)性和可擴(kuò)展性。
  • 可擴(kuò)展性:可以輕松地添加新的發(fā)布者和訂閱者,而無(wú)需修改現(xiàn)有的代碼。這使得系統(tǒng)能夠靈活地適應(yīng)不斷變化的需求。
  • 靈活性:支持多個(gè)訂閱者同時(shí)訂閱同一個(gè)事件,并且可以根據(jù)需要定制事件的處理方式。這種靈活性使得系統(tǒng)能夠應(yīng)對(duì)各種復(fù)雜場(chǎng)景。
  • 時(shí)間解耦:發(fā)布者可以在任何時(shí)刻發(fā)布事件,而訂閱者則可以在自己方便的時(shí)候處理這些事件。這種時(shí)間解耦性使得系統(tǒng)更加靈活和高效。

綜上所述,發(fā)布-訂閱模式提供了一種強(qiáng)大而靈活的方式來(lái)處理組件之間的通信和協(xié)作,使得系統(tǒng)更加健壯、可維護(hù)和可擴(kuò)展。在Vue.js 等現(xiàn)代前端框架中,發(fā)布-訂閱模式被廣泛應(yīng)用于組件之間的通信和狀態(tài)管理。

實(shí)現(xiàn)發(fā)布-訂閱模式

在深入探討發(fā)布-訂閱模式時(shí),其核心機(jī)制在于一個(gè)精心構(gòu)建的事件中心。這個(gè)事件中心不僅作為消息的中轉(zhuǎn)站,還承載著存儲(chǔ)事件和訂閱者之間關(guān)系的重要職責(zé)。

事件中心

定義一個(gè) EventBus 類,用于存儲(chǔ)事件和訂閱者關(guān)系,代碼如下:

interface EventType {
  readonly callback: Function
  readonly once: boolean
}

type EventsType = Record<string, EventType[]>
class EventEmitter {
  private events: EventsType = {};
}

events 是一個(gè)對(duì)象,其中每個(gè)鍵都是事件名稱,值是一個(gè)由 EventType 對(duì)象組成的數(shù)組,EventType 對(duì)象中包含是否只訂閱一次標(biāo)志位和回調(diào)函數(shù)。

發(fā)布事件

定義一個(gè) emit 方法,用于發(fā)布事件,代碼如下:

type EventArgs = Record<string, number | string | object | boolean>

interface EventType {
  readonly callback: Function
  readonly once: boolean
}

type EventsType = Record<string, EventType[]>

class EventEmitter {
  private events: EventsType = {}
  
  emit(eventName: string, eventArgs: EventArgs) {
    eventName?.split(',').forEach((eventKey: string) => {
      eventKey = eventKey.trim()
      const events = this.events[eventKey] || []
      let { length } = events

      for (let i = 0; i < length; i++) {
        const { callback, once } = events[i]
        if (once) {
          events.splice(i, 1)
          if (length === 0) {
            delete this.events[eventKey]
          }
          length--
          i--
        }

        callback.apply(this, [eventArgs])
      }
    })
  }
}

emit 方法接收兩個(gè)參數(shù),第一個(gè)參數(shù) eventName 為事件名稱,第二個(gè)參數(shù) eventArgs 為事件參數(shù)。其中 eventName 參數(shù)可以是一個(gè)以逗號(hào)分隔的字符串,表示同時(shí)發(fā)布多個(gè)事件。核心邏輯便是遍歷 events 對(duì)象,找到對(duì)應(yīng)的事件名稱,然后遍歷事件名稱對(duì)應(yīng)的事件數(shù)組,依次通過(guò)調(diào)用 apply 方法,執(zhí)行回調(diào)函數(shù)。

訂閱事件

定義一個(gè) on 方法,用于訂閱事件,代碼如下:

class EventEmitter {
  private events: EventsType = {}

  on(eventName: string, callback: CallbackType, once?: boolean) {
    eventName?.split(',').forEach((eventKey: string) => {
      eventKey = eventKey.trim()
      if (!this.events[eventKey]) {
        this.events[eventKey] = [];
      } else {
        this.events[eventKey].push({
          callback,
          once: !!once
        })
      }
    })

    return this
  }
}

on 方法接收三個(gè)參數(shù),第一個(gè)參數(shù) eventName 為事件名稱,第二個(gè)參數(shù) callback 為回調(diào)函數(shù),第三個(gè)參數(shù) once 表示是否只訂閱一次。核心邏輯是遍歷 eventName 參數(shù) split 之后的數(shù)組對(duì)象(允許同時(shí)監(jiān)聽(tīng)多個(gè)事件,多個(gè)事件之間以逗號(hào)分隔),將事件名稱拆分成數(shù)組,然后遍歷數(shù)組,將回調(diào)函數(shù)存入 events 對(duì)象中。

取消訂閱事件

定義一個(gè) off 方法,用于取消訂閱事件,代碼如下:

class EventEmitter {
  private events: EventsType = {}

  off(eventName: string, callback?: CallbackType) {
    // 如果不傳callback,就清除所有事件
    if (!eventName) {
      this.events = {}
    }
    eventName?.split(',').forEach((eventKey: string) => {
      if(!callback) {
        delete this.events[eventKey]
      }
      const events = this.events[eventKey] || []
      let { length } = events
      for (let i = 0; i < length; i++) {
        if (events[i].callback === callback) {
          events.splice(i, 1)
          length --
          i --
        }
      }

      if (events.length === 0) {
        delete this.events[eventKey]
      }
    })

    return this
  }
}

off 方法接收兩個(gè)參數(shù),第一個(gè)參數(shù) eventName 為事件名稱,第二個(gè)參數(shù) callback 為回調(diào)函數(shù),核心邏輯是遍歷 eventName 參數(shù) split 之后的數(shù)組對(duì)象(允許同時(shí)取消訂閱多個(gè)事件,多個(gè)事件之間以逗號(hào)分隔),將事件名稱拆分成數(shù)組,然后遍歷數(shù)組,將回調(diào)函數(shù)從數(shù)組中刪除。

只訂閱一次

定義一個(gè) once 方法,用于只訂閱一次,代碼如下:

class EventEmitter {
  private events: EventsType = {}

  once(eventName: string, callback: CallbackType) {
    return this.on(eventName, callback, true)
  }
}

once 方法接收兩個(gè)參數(shù),第一個(gè)參數(shù) eventName 為事件名稱,第二個(gè)參數(shù) callback 為回調(diào)函數(shù)。once 方法內(nèi)部調(diào)用 on 方法,并將第三個(gè)參數(shù)設(shè)置為 true,表示只訂閱一次。

如何在 Vue 中使用

當(dāng)我們想要在 Vue 應(yīng)用中使用發(fā)布-訂閱模式時(shí),通常會(huì)引入一個(gè)全局的事件總線 (Event Bus) 來(lái)作為通信的中心。這樣,無(wú)論組件之間有著怎樣的層級(jí)關(guān)系,它們都可以輕松地通過(guò)事件總線進(jìn)行通信。

為了在 Vue 應(yīng)用中實(shí)現(xiàn)這一功能,我們需要在應(yīng)用的入口文件(通常是 main.tsmain.js,取決于你的項(xiàng)目配置和所使用的 TypeScriptJavaScript)中引入并實(shí)例化事件總線。然后,我們可以利用 Vueprovide 方法將事件總線注冊(cè)為全局對(duì)象,使得在 Vue 應(yīng)用的任何組件中都能通過(guò) inject 來(lái)訪問(wèn)它。

main.ts 中編寫代碼如下:

import { createApp } from 'vue'
import { EventEmitter } from '@qftjs/tiny-editor-core'
import App from './App.vue'

const app = createApp(App)

const bus = new EventEmitter()
app.provide('$bus', bus)

app.mount('#app')

在 Vue 組件中通過(guò) inject 方法注入 $bus 對(duì)象,然后就可以使用 $bus 對(duì)象進(jìn)行事件訂閱和事件發(fā)布。具體代碼如下:

<script setup lang="ts">
import { inject } from 'vue'

const $bus = inject('$bus')

$bus.emit('dragStart')
</script>

以上就是Vue3中自定義事件總線的實(shí)現(xiàn)代碼的詳細(xì)內(nèi)容,更多關(guān)于Vue3自定義事件總線的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue 基礎(chǔ)語(yǔ)法之計(jì)算屬性(computed)、偵聽(tīng)器(watch)、過(guò)濾器(filters)詳解

    Vue 基礎(chǔ)語(yǔ)法之計(jì)算屬性(computed)、偵聽(tīng)器(watch)、過(guò)濾器(filters)詳解

    計(jì)算屬性就是 Vue 實(shí)例選項(xiàng)中的 computed,computed 的值是一個(gè)對(duì)象類型,對(duì)象中的屬性值為函數(shù),而且這個(gè)函數(shù)沒(méi)辦法接收參數(shù),這篇文章主要介紹了Vue 基礎(chǔ)語(yǔ)法之計(jì)算屬性(computed)、偵聽(tīng)器(watch)、過(guò)濾器(filters)詳解,需要的朋友可以參考下
    2022-11-11
  • 在vue中封裝的彈窗組件使用隊(duì)列模式實(shí)現(xiàn)方法

    在vue中封裝的彈窗組件使用隊(duì)列模式實(shí)現(xiàn)方法

    這篇文章主要介紹了在vue中封裝的彈窗組件使用隊(duì)列模式實(shí)現(xiàn)方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Vue可自定義tab組件用法實(shí)例

    Vue可自定義tab組件用法實(shí)例

    在本篇文章里小編給大家分享了關(guān)于Vue可自定義tab組件用法實(shí)例以及相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-10-10
  • 實(shí)例解析Vue.js下載方式及基本概念

    實(shí)例解析Vue.js下載方式及基本概念

    vue是一套用于構(gòu)建用戶界面的漸進(jìn)式框架。接下來(lái)通過(guò)本文給大家分享Vue.js下載方式及基本概念,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • Vue+thinkphp5.1+axios實(shí)現(xiàn)文件上傳

    Vue+thinkphp5.1+axios實(shí)現(xiàn)文件上傳

    這篇文章主要為大家詳細(xì)介紹了Vue+thinkphp5.1+axios實(shí)現(xiàn)文件上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 關(guān)于vue父組件調(diào)用子組件的方法

    關(guān)于vue父組件調(diào)用子組件的方法

    本文主要介紹了vue父組件調(diào)用子組件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • vue+elementui(對(duì)話框中form表單的reset問(wèn)題)

    vue+elementui(對(duì)話框中form表單的reset問(wèn)題)

    這篇文章主要介紹了vue+elementui(對(duì)話框中form表單的reset問(wèn)題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue?cli3.0創(chuàng)建Vue項(xiàng)目的簡(jiǎn)單過(guò)程記錄

    Vue?cli3.0創(chuàng)建Vue項(xiàng)目的簡(jiǎn)單過(guò)程記錄

    Vue CLI是一個(gè)基于Vue.js進(jìn)行快速開(kāi)發(fā)的完整系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于Vue?cli3.0創(chuàng)建Vue項(xiàng)目的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • vuex-persist 使用場(chǎng)景分析

    vuex-persist 使用場(chǎng)景分析

    Vuex-Persist 是一個(gè)用于在 Vuex 中實(shí)現(xiàn)持久化狀態(tài)的庫(kù),它可以用來(lái)解決應(yīng)用程序在刷新瀏覽器或關(guān)閉頁(yè)面后丟失 Vuex store 中狀態(tài)的問(wèn)題,本文給大家介紹vuex-persist 可以用來(lái)干什么,感興趣的朋友一起看看吧
    2023-11-11
  • ElementUI?復(fù)雜頂部和左側(cè)導(dǎo)航欄實(shí)現(xiàn)示例

    ElementUI?復(fù)雜頂部和左側(cè)導(dǎo)航欄實(shí)現(xiàn)示例

    本文主要介紹了ElementUI?復(fù)雜頂部和左側(cè)導(dǎo)航欄實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評(píng)論

临安市| 右玉县| 阳新县| 辰溪县| 通海县| 渝北区| 自贡市| 溧阳市| 宣城市| 富阳市| 松溪县| 苏尼特左旗| 岢岚县| 施秉县| 新余市| 洮南市| 名山县| 南安市| 保亭| 临澧县| 彰武县| 射洪县| 海安县| 电白县| 福泉市| 河间市| 商洛市| 固阳县| 鲁山县| 兴业县| 新民市| 巨野县| 扎囊县| 汪清县| 枣阳市| 丰宁| 广灵县| 河东区| 沛县| 南安市| 赤峰市|