Vue Academy #5: Communication between components
Tags: vue, webdev, javascript, typescript
Published: 2021-08-21 09:34:43

When you pass props from parent to children, you might need to update this data.

In vuejs you have two ways to handle this case, the most used is to `emit` an event from the children to the parent. The other way is to use `bus event`.

### Emit event from children

In component paradigm, we have a component in the component in component ... From one parent you can pass multiple data in another child component, called `props`. 

In some cases, you will need to **update** these props from one of these ** child components**!

Should you update these props directly? **NO**! 

If you try to make this on a props object, vue will trigger a `warn` about this manipulation. You mustn't **DO** this!

⚠️ Mutating props like this is considered to be an anti-pattern!

**Two rules:**

- Only the component can change its state

- Only the parent of the component can change the props

So how can you update the props from children properly ?!

Use `emit event`!

1) Emit an event from the child component with the new value to update the props in this event.

2) Handle this event in the parent and update the data!

A short example 👇

Context: We need to update props when clicking on

*Child.vue*

```vue
<template>
<div>
     <!-- When we click on button, we want to update value -->
    <button @click="updateCounter(counter + 1)">
</div>
</template>
<script>
import Vue from "vue"

export default Vue.extend({
    props: {
        counter: Number,
    },
    methods: {
       updateCounter(newValue) {
         // 1) Emit event from child with the new value
         this.$emit('update-counter', newValue)
       }
    }
})
</script>
```

*Parent.vue*

```vue
<template>
<div>
    <child
       :counter="counter"
       <!-- 2) We handle the update event and we update the current props value ! -->
       @update-counter="counter = $event"
       />
</div>
</template>
<script>
import Vue from "vue"
// We omit Child component import

export default Vue.extend({
    components: {
       Child,
    },
    data() {
        return {
            counter: 0,
        }
    },
})
</script>
```

As you can see it can be easy to update props value from children! If you have more deep children like this 👇

Parent -> Child one -> Child Two

*Child two has two parents, Parent and Child One.*

If you need to **update props** from **Child two**, you can emit an event to **Child One**, and emit another event to **Parent**!

In general, this tip is *efficient*, but in some cases, you will need to communicate from one component to another component that is **not linked by parent**, for example, imagine that your Footer needs to communicate with your Header. 

You **cannot** emit events between them!

How to handle this?

### Bus Event

Vue allows us to use bus events!

It's a way to emit data between both components without using **Parent** !

First, we need to create our bus event!

```js
import Vue from 'vue'
import App from './App.vue'


export const bus = new Vue()

new Vue({
  render: h => h(App),
}).$mount('#app')
```

*Footer.vue*

```vue
<script>
import Vue from "vue"
// We omit template and bus import

export default Vue.extend({
    methods {
        emitValueWithBus(value) {
           // Emit value thanks to the bus
           bus.$emit('update-value', 'toto')
        }
    },
})
</script>
```

*Header.vue*

```vue
<script>
import Vue from "vue"
// We omit template and bus import

export default Vue.extend({
   // Init the bus connection when created component
   created () {
       // Get value from event with the bus event
       bus.$on('update-value', (data) => {
          // data is equal to 'toto' !
       })
   },
   destroyed() {
      // When component is destroyed we should remove listener
      bus.$off()
   }
})
</script>
```

📝 *Note: We remove listener manually, vue handle this case for bus event automatically*

### Conclusion

As we have seen before if you need to update props value you need to handle it in the parent component thanks to `event`!

But in some cases we can't use these tips, so we need to use the `event bus`!


---

I hope you like this reading!

🎁 You can get my new book `Underrated skills in javascript, make the difference` for FREE if you follow me on [Twitter](https://twitter.com/code__oz) and MP me 😁

Or get it [HERE](https://codeoz.gumroad.com/l/RXLYp)

🎁 [MY NEWSLETTER](https://www.getrevue.co/profile/code__oz)

☕️ You can [SUPPORT MY WORKS](https://www.buymeacoffee.com/CodeoZ) 🙏

🏃‍♂️ You can follow me on 👇

🕊 Twitter : [https://twitter.com/code__oz](https://twitter.com/code__oz)

👨‍💻 Github: https://github.com/Code-Oz

And you can mark 🔖 this article!