There is no event bus in Vue 3. So $on will not work. See: https://v3-migration.vuejs.org/breaking-changes/events-api.html#events-api
It is recommended that you create your event bus with external libraries, unless you want to make use of the supported parent-children event-based communication in which the child emits an event which can only be listened to by the parent. See: https://v3.vuejs.org/guide/component-custom-events.html#custom-events
To implement an event bus for your application, make sure that you are emitting (firing) the events and listening to them with the same instance of the emitter. Else, it won't work.
I preferred emittery (https://github.com/sindresorhus/emittery) for event bus with Vue js. It is robust with excellent Typescript support. I also use it on Node js via the Adonisjs framework.
Create a useEvent hook
//file: composables/useEvent.ts
import Emittery from 'emittery';
const emitter = new Emittery();
// Export the Emittery class and its instance.
// The `emitter` instance is more important for us here
export {emitter, Emittery};
// Export the Emittery class and its instance
export { emitter, Emittery };
- In any vue component listen to an event
// file: AnyVueComponent.vue
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../composables/useEvent'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
onMounted(() => {
emitter.on('event-name', async () => {
// Perform actions. async...await is supported
});
})
return {};
},
});
</script>
- In any vue component emit the event
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../composables/useEvent'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
void emitter.emit('event-name');
return {};
},
});
</script>
- Note that you can import the
useEvent hook into any non-Vue file and it will work. It is just a JS/TS file.
For the Quasar Framework:
- Create a boot file
./node_modules/.bin/quasar new boot EventBus --format ts
- // file: EventBus.ts
import { boot } from 'quasar/wrappers';
import Emittery from 'emittery';
const emitter = new Emittery();
export default boot(({ app }) => {
app.config.globalProperties.$event = emitter;
});
// Export the Emittery class and its instance
export { emitter, Emittery };
- Register with the
quasar.conf.js file
module.exports = configure(function(/* ctx */){
return {
boot: [
...,
'EventBus',
],
}
}
- In any vue component listen to an event
// file: AnyVueComponent.vue
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../boot/EventBus'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
onMounted(() => {
emitter.on('event-name', async () => {
// Perform actions. async...await is supported
});
})
return {};
},
});
</script>
- In any vue component emit the event
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../boot/EventBus'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
void emitter.emit('event-name');
return {};
},
});
</script>