Skip to content

useBus

A composable that provides an event bus interface for a specific event type, allowing components to communicate with each other without direct parent-child relationships.

Usage

ts
import { useBus } from '#imports'

// Create a typed event bus
const counterBus = useBus<number>('counter')

// In component A: emit an event
function increment() {
  counterBus.emit(1)
}

// In component B: listen for the event
counterBus.on((value) => {
  console.log(`Counter incremented by: ${value}`)
})

Type Signature

ts
function useBus<Payload = unknown | undefined>(type: EventType): {
  on: (handler: Handler<Payload>) => void;
  off: (handler: Handler<Payload>) => void;
  emit: (payload: Payload) => void;
  all: Map<EventType, Handler[]>;
  listeners: ComputedRef<Handler<Payload>[]>;
}

Parameters

ParameterTypeDescription
typeEventTypeThe event type identifier (string or symbol)

Return Value

PropertyTypeDescription
on(handler: Handler<Payload>) => voidRegister an event handler that automatically gets cleaned up on component unmount
off(handler: Handler<Payload>) => voidManually remove an event handler
emit(payload: Payload) => voidEmit an event with the specified payload
allMap<EventType, Handler[]>Map of all registered event handlers
listenersComputedRef<Handler<Payload>[]>Computed reference to all handlers for this event type

Automatic Cleanup

Event handlers registered with the on method are automatically removed when the component is unmounted, preventing memory leaks and unexpected behavior.

Example: Component Communication

vue
<!-- ComponentA.vue -->
<script setup>
import { useBus } from '#imports'

const messageBus = useBus('message')

function sendMessage() {
  messageBus.emit('Hello from Component A!')
}
</script>

<template>
  <button @click="sendMessage">Send Message</button>
</template>
vue
<!-- ComponentB.vue -->
<script setup>
import { useBus } from '#imports'
import { ref } from 'vue'

const lastMessage = ref('')
const messageBus = useBus('message')

messageBus.on((message) => {
  lastMessage.value = message
})
</script>

<template>
  <div>Last message received: {{ lastMessage }}</div>
</template>

Source Code