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 ​