DEV Community

Cover image for Vue Academy #5: Communication between components
Code Oz
Code Oz

Posted on • Edited on

Vue Academy #5: Communication between components

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

<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>
Enter fullscreen mode Exit fullscreen mode

Parent.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>
Enter fullscreen mode Exit fullscreen mode

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!

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


export const bus = new Vue()

new Vue({
  render: h => h(App),
}).$mount('#app')
Enter fullscreen mode Exit fullscreen mode

Footer.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>
Enter fullscreen mode Exit fullscreen mode

Header.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>
Enter fullscreen mode Exit fullscreen mode

📝 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 and MP me 😁

Or get it HERE

🎁 MY NEWSLETTER

☕️ You can SUPPORT MY WORKS 🙏

🏃‍♂️ You can follow me on 👇

🕊 Twitter : https://twitter.com/code__oz

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

And you can mark 🔖 this article!

Top comments (2)

Collapse
 
blazejplis profile image
Blazej Plis

Great! Thank you for that, yesterday I started creating my todo app and was stuck exactly on emit, and couldn't find a way to make it work, but thanks to your tutorial it's working!

Collapse
 
codeoz profile image
Code Oz

Wow very nice comment! I am so happy to see that it can help some people 👍😁