Communication between components in Vue with Mitt() emitter

December 2nd, 2022

With mitt emitter, you can communicate between different components (doesn't matter if child-parent, siblings, grandchild,... )

With Vue emit events: only child -> parent

  1. install mitt(): npm install mitt

  2. main.js: import mitt, provide it for all components

1import { createApp } from "vue";
2import mitt from 'mitt' <!--[tl!: highlight]-->
3import App from "./App.vue";
4 
5const emitter = mitt() <!--[tl!: highlight]-->
6 
7createApp(App)
8 // provide emitter for all components
9 .provide('emitter', emitter) <!--[tl!: highlight]-->
10 .mount("#app");
  1. inject emitter in the component where you need it, if response is ok, emit event 'dataSaved'

1<script setup>
2import { ref, inject } from "vue";
3 
4const emitter = inject('emitter');
5 
6const enteredName = ref('');
7const chosenRating = ref(null);
8 
9function submit() {
10 fetch(url, {
11 method: 'POST',
12 headers: {
13 'Content-Type': 'application/json'
14 },
15 body: JSON.stringify({
16 name: enteredName.value,
17 rating: chosenRating.value
18 })
19 }).then(response => {
20 if (response.ok) {
21 // if response ok -> emit event 'dataSaved'
22 emitter.emit('dataSaved', {a: 'b'});
23 }
24 });
25 
26 enteredName.value = '';
27 chosenRating.value = null;
28}
29 
30</script>
  1. listen for event 'dataSaved' in another component (doesn't matter in what relationship is with this component)

1<script setup>
2import { inject, onMounted, ref } from "vue"; <!--[tl!:highlight:8]-->
3 
4let emitter = inject('emitter');
5 
6emitter.on('dataSaved', (passedData) => {
7 console.log('data was saved, passedData = ', passedData)
8 loadData();
9})
10 
11function loadData() {
12 // fetch data from database
13}
14 
15onMounted(() => loadData());
16 
17</script>

Related Posts