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

Vue消息訂閱與發(fā)布過(guò)程

 更新時(shí)間:2025年11月03日 09:54:26   作者:咖啡の貓  
發(fā)布-訂閱模式是一種設(shè)計(jì)模式,通過(guò)事件中心實(shí)現(xiàn)對(duì)象間的解耦通信,在Vue中,Vue2使用Vue實(shí)例作為事件總線,Vue3推薦使用mitt庫(kù),發(fā)布-訂閱模式適用于廣播通知、解耦組件和復(fù)雜狀態(tài)管理,在選擇工具時(shí),建議根據(jù)場(chǎng)景選擇合適的工具

一、什么是發(fā)布-訂閱模式?

發(fā)布-訂閱模式 是一種對(duì)象間通信的設(shè)計(jì)模式,包含三個(gè)核心角色:

  • 發(fā)布者(Publisher):發(fā)出消息(事件)
  • 訂閱者(Subscriber):監(jiān)聽(tīng)并處理消息
  • 事件中心(Event Channel):中介,負(fù)責(zé)消息的注冊(cè)與分發(fā)

類(lèi)比理解

想象一個(gè)“廣播電臺(tái)”:

  • 電臺(tái)(事件中心)負(fù)責(zé)廣播
  • 主持人(發(fā)布者)說(shuō):“現(xiàn)在是北京時(shí)間 8 點(diǎn)整”
  • 聽(tīng)眾(訂閱者)聽(tīng)到后,各自執(zhí)行動(dòng)作(起床、煮咖啡、打卡)

發(fā)布者無(wú)需知道誰(shuí)在聽(tīng),訂閱者也無(wú)需知道誰(shuí)在說(shuō),實(shí)現(xiàn)解耦。

二、核心概念:訂閱、發(fā)布、取消訂閱

操作方法說(shuō)明
訂閱on(event, callback)注冊(cè)事件監(jiān)聽(tīng)器
發(fā)布emit(event, ...args)觸發(fā)事件,傳遞數(shù)據(jù)
取消訂閱off(event, callback)移除監(jiān)聽(tīng),防止內(nèi)存泄漏

三、在 Vue 中的實(shí)現(xiàn)方式

1. Vue 2:使用 Vue 實(shí)例作為事件總線

Vue 2 的實(shí)例本身實(shí)現(xiàn)了事件接口($on$emit、$off),可直接用作事件中心。

(1) 創(chuàng)建 EventBus

// utils/eventBus.js
import Vue from 'vue'

// 創(chuàng)建一個(gè) Vue 實(shí)例作為全局事件中心
const EventBus = new Vue()

export default EventBus

(2) 訂閱消息(在組件中)

<!-- NotificationBar.vue -->
<script>
import EventBus from '@/utils/eventBus'

export default {
  data() {
    return {
      message: ''
    }
  },
  created() {
    // 訂閱 'show-notification' 事件
    EventBus.$on('show-notification', (msg, type) => {
      this.message = `[${type}] ${msg}`
      this.show()
    })
  },
  beforeDestroy() {
    // 組件銷(xiāo)毀時(shí)取消訂閱,避免內(nèi)存泄漏
    EventBus.$off('show-notification')
  },
  methods: {
    show() {
      // 顯示通知
      console.log(this.message)
    }
  }
}
</script>

(3) 發(fā)布消息

<!-- LoginButton.vue -->
<script>
import EventBus from '@/utils/eventBus'

export default {
  methods: {
    login() {
      // 發(fā)布登錄成功事件
      EventBus.$emit('user-logged-in', { id: 1, name: 'Alice' })
      
      // 發(fā)布全局通知
      EventBus.$emit('show-notification', '登錄成功!', 'success')
    }
  }
}
</script>

實(shí)現(xiàn)了跨組件通信,但需手動(dòng)管理生命周期。

2. Vue 3:使用mitt庫(kù)(推薦)

Vue 3 移除了實(shí)例上的 $on、$off 方法,因此不能再使用 Vue 實(shí)例作為事件總線。

(1) 安裝 mitt

npm install mitt

mitt 是一個(gè)超輕量(<200B)的事件發(fā)射器,API 簡(jiǎn)潔,完美替代。

(2) 創(chuàng)建全局事件中心

// utils/eventBus.js
import mitt from 'mitt'

// 創(chuàng)建事件中心
const EventBus = mitt()

export default EventBus

(3) 在 Vue 3 組件中使用

<!-- NotificationBar.vue -->
<script setup>
import { onMounted, onUnmounted } from 'vue'
import EventBus from '@/utils/eventBus'

// 訂閱事件
const handleNotification = (data) => {
  console.log(`[通知] ${data.type}: ${data.msg}`)
}

onMounted(() => {
  EventBus.on('show-notification', handleNotification)
})

// 取消訂閱
onUnmounted(() => {
  EventBus.off('show-notification', handleNotification)
})
</script>
<!-- LoginButton.vue -->
<script setup>
import EventBus from '@/utils/eventBus'

function login() {
  // 發(fā)布事件
  EventBus.emit('user-logged-in', { id: 1, name: 'Bob' })
  EventBus.emit('show-notification', {
    msg: '登錄成功!',
    type: 'success'
  })
}
</script>

<template>
  <button @click="login">登錄</button>
</template>

mitt 支持 TypeScript,API 簡(jiǎn)潔:on、emit、offclear。

四、手寫(xiě)一個(gè)簡(jiǎn)易的 Event Hub

為了理解原理,我們來(lái)實(shí)現(xiàn)一個(gè)極簡(jiǎn)版的事件中心:

// utils/EventHub.js
class EventHub {
  constructor() {
    this.events = {}
  }

  // 訂閱
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = []
    }
    this.events[event].push(callback)
  }

  // 發(fā)布
  emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback(...args))
    }
  }

  // 取消訂閱
  off(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(cb => cb !== callback)
    }
  }

  // 清除所有
  clear(event) {
    if (event) {
      delete this.events[event]
    } else {
      this.events = {}
    }
  }
}

export default new EventHub()

核心就是維護(hù)一個(gè)事件-回調(diào)函數(shù)的映射表。

五、發(fā)布-訂閱 vs 其他通信方式

通信方式方向耦合度適用場(chǎng)景
發(fā)布-訂閱任意廣播通知、解耦組件
props / emit父↔子緊密相關(guān)的父子組件
Pinia任意共享狀態(tài)、復(fù)雜邏輯
Provide/Inject祖→孫主題、配置傳遞

選擇建議:

  • 狀態(tài)共享 → Pinia
  • 簡(jiǎn)單通知 → mitt
  • 祖先傳值 → provide/inject

六、最佳實(shí)踐與注意事項(xiàng)

1. 使用語(yǔ)義化事件名

// ? 避免模糊命名
EventBus.emit('click')

// ? 使用前綴和語(yǔ)義化命名
EventBus.emit('user:login-success', user)
EventBus.emit('cart:item-added', item)

2. 務(wù)必取消訂閱

// Vue 2
beforeDestroy() {
  EventBus.$off('event-name')
}

// Vue 3 Composition API
onUnmounted(() => {
  EventBus.off('event-name', handler)
})

忘記 off 會(huì)導(dǎo)致內(nèi)存泄漏重復(fù)觸發(fā)。

3. 避免過(guò)度使用

  • 不要用事件總線代替狀態(tài)管理
  • 復(fù)雜狀態(tài)同步 → 使用 Pinia
  • 事件過(guò)多 → 考慮模塊化事件中心

4. TypeScript 支持

// types/events.ts
type Events = {
  'user:login': (user: User) => void
  'cart:update': (count: number) => void
  'app:loading': (status: boolean) => void
}

// utils/eventBus.ts
import mitt from 'mitt'
export const useEventBus = () => mitt<Events>()

類(lèi)型安全,IDE 自動(dòng)提示。

七、現(xiàn)代替代方案:Pinia + Actions

對(duì)于大多數(shù)場(chǎng)景,Pinia 是更優(yōu)解:

// stores/appStore.ts
import { defineStore } from 'pinia'

export const useAppStore = defineStore('app', {
  state: () => ({
    user: null,
    cartCount: 0,
    isLoading: false
  }),
  actions: {
    login(user) {
      this.user = user
      // 其他組件自動(dòng)響應(yīng)
    },
    addToCart(item) {
      this.cartCount++
    },
    setLoading(status) {
      this.isLoading = status
    }
  }
})
<!-- 任何組件 -->
<script setup>
import { useAppStore } from '@/stores/appStore'

const appStore = useAppStore()

// 直接調(diào)用 action
appStore.login(userData)
</script>

響應(yīng)式、可調(diào)試、支持 SSR。

八、總結(jié)

核心點(diǎn)說(shuō)明
本質(zhì)解耦的事件驅(qū)動(dòng)通信
角色發(fā)布者、訂閱者、事件中心
Vue 2new Vue() 作為 EventBus
Vue 3使用 mitt 庫(kù)
優(yōu)點(diǎn)靈活、解耦、輕量
缺點(diǎn)難以追蹤、易內(nèi)存泄漏
推薦簡(jiǎn)單通知用 mitt,狀態(tài)用 Pinia

一句話總結(jié):

發(fā)布-訂閱是“消息廣播”,而 Pinia 是“狀態(tài)中心”——根據(jù)場(chǎng)景選擇合適的工具。

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

相關(guān)文章

  • Vue3中pinia用法示例

    Vue3中pinia用法示例

    這篇文章主要介紹了Vue3中使用pinia,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • VUE使用 wx-open-launch-app 組件開(kāi)發(fā)微信打開(kāi)APP功能

    VUE使用 wx-open-launch-app 組件開(kāi)發(fā)微信打開(kāi)APP功能

    這篇文章主要介紹了VUE使用 wx-open-launch-app 組件開(kāi)發(fā)微信打開(kāi)APP功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • vue使用codemirror的兩種用法

    vue使用codemirror的兩種用法

    這篇文章主要介紹了在vue里使用codemirror的兩種用法,每種方法通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Element中Slider滑塊的具體使用

    Element中Slider滑塊的具體使用

    這篇文章主要介紹了Element中Slider滑塊的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Vue中引入swiper報(bào)錯(cuò)的問(wèn)題及解決

    Vue中引入swiper報(bào)錯(cuò)的問(wèn)題及解決

    這篇文章主要介紹了Vue中引入swiper報(bào)錯(cuò)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue中v-for 循環(huán)對(duì)象中的屬性

    vue中v-for 循環(huán)對(duì)象中的屬性

    這篇文章主要介紹了 vue中v-for 循環(huán)對(duì)象中的屬性,文章圍繞v-for 循環(huán)對(duì)象的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,需要的朋友可以參考一下,希望對(duì)大家有所幫助
    2021-11-11
  • Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例

    Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例

    這篇文章主要介紹了Vue循環(huán)中多個(gè)input綁定指定v-model實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • vue-router的使用方法及含參數(shù)的配置方法

    vue-router的使用方法及含參數(shù)的配置方法

    這篇文章主要介紹了vue-router的使用方法及含參數(shù)的配置方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • 詳解vuex的簡(jiǎn)單使用

    詳解vuex的簡(jiǎn)單使用

    這篇文章主要介紹了詳解vuex的簡(jiǎn)單使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • vue3中v-model的用法詳解

    vue3中v-model的用法詳解

    vue 提供了很多自定義指令,大大方便了我們的開(kāi)發(fā),其中最常用的也就是 v-model,他可以在組件上使用以實(shí)現(xiàn)雙向綁定。它可以綁定多種數(shù)據(jù)結(jié)構(gòu), 今天總結(jié)一下用法
    2023-04-04

最新評(píng)論

囊谦县| 辽阳县| 湄潭县| 洛扎县| 双鸭山市| 临沂市| 大足县| 喀喇沁旗| 云浮市| 宜春市| 潼南县| 壤塘县| 布尔津县| 河北区| 神木县| 甘洛县| 桃园市| 麻江县| 江北区| 温泉县| 沁水县| 永新县| 晋宁县| 隆回县| 牟定县| 赤壁市| 达日县| 平罗县| 平舆县| 隆安县| 广元市| 抚松县| 富川| 镇坪县| 鄂州市| 武威市| 平度市| 墨玉县| 乌拉特前旗| 武汉市| 鄂托克前旗|