I watched a video to understand how to use event bus to communicate between siblings, and in the video there was a parent with some data that was sent to the childs as a prop, then a method in one of the childs modified that prop and used an event bus to send it to the other child.
I thought, whats the point of the prop? Why cant i just use the siblings own data? And thats what i did:
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
export const bus = new Vue() //Event Bus
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<ComponenteA></ComponenteA>
<ComponenteB></ComponenteB>
</div>
</template>
<script>
import ComponenteA from './components/ComponenteA.vue'
import ComponenteB from './components/ComponenteB.vue'
export default {
name: 'App',
components:{
ComponenteA,
ComponenteB
}
}
</script>
ComponentA.vue
<template>
<div>
<h1 @click="changeTitle">Componente A</h1>
</div>
</template>
<script>
import { bus } from '../main'
export default {
name: 'ComponenteA',
data(){
return{
title: ''
}
},
methods:{
changeTitle(){
this.title = 'Title emitted from A a B'
bus.$emit('titleChanged',this.title)
}
}
}
</script>
ComponentB.vue
<template>
<div>
<h1>Componente B -> {{title}}</h1>
</div>
</template>
<script>
import { bus } from '../main'
export default {
name: 'ComponenteB',
data(){
return{
title: ''
}
},
created(){
bus.$on('titleChanged', (payload) =>{
this.title = payload
})
}
}
</script>
Is there anything wrong with my code? Is there a reason for using the parent data that im failing to see?
The reason that the data should start in the parent and get passed down to the children is because of a couple things:
The reactivity system in Vue.js is built around having your data in a single place (a "single source of truth"), then passing that data to wherever it is needed. Now, if only a single component needs the data, you'll just store that data on the component. But the data is needed in multiple components, you'll want to store it in a parent and then pass it to the children. This becomes particularly obvious if you need to start using Vuex.
If for some reason you need to change, say, the name of the data (e.g., pageTitle
instead of title
), it becomes far easier to trace where the data came from if it always comes from a parent. Relying on the event bus across siblings can become rather brittle as the project grows larger.
So, in your case, the title
should really exist in the data
of your App.vue
component. Each of the children would receive it as a prop. Then, if the title
was changed, $emit()
an event that App.vue
is listening for. That event would change the data in App.vue
.
Take a look at this question for more details:
vuejs update parent data from child component