Replace the bus with a tiny emitter
The quickest migration keeps the pattern and swaps the implementation for a small library such as mitt:
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
// ProductList.vue
mounted() {
EventBus.$on('cart:add', this.onAdd)
},
beforeDestroy() {
EventBus.$off('cart:add', this.onAdd)
},
// AddButton.vue
EventBus.$emit('cart:add', product)// event-bus.js
import mitt from 'mitt'
export const emitter = mitt()
// ProductList.vue
mounted() {
emitter.on('cart:add', this.onAdd)
},
beforeUnmount() {
emitter.off('cart:add', this.onAdd)
},
// AddButton.vue
emitter.emit('cart:add', product)Better long term options
- Props and emits for parent and child communication.
- provide and inject for a subtree that shares state.
- Pinia (or Vuex 4) for application state that many components read and change.
Lifecycle hook events
this.$once('hook:beforeDestroy', fn) also relied on the instance emitter. In Vue 3, use the lifecycle hook directly, or @vue:mounted style listeners on child components in templates.
How vueleap detects it
vueleap reports each $on, $off and $once call (rule event-emitter, compat flag INSTANCE_EVENT_EMITTER), the new Vue() that creates the bus (rule global-mount), and hook: events (rule hook-events). Template @hook:mounted listeners are rewritten to @vue:mounted by --fix.
Run it on your project:
npx vueleap