Communicating between Vue.js components

/ #Vue.js


When you're building a Vue.js app you often need to send information from a component to another, here is how you do that.

Passing variables to a child component

We can pass variablese to child components using props. You should never change that prop inside a component as they are immutable. If you update the prop from the parent component the prop will be sent to the child and the content will be rerendered.

Example of passing props to a child component:

<div id="app">
  <shopping-cart :quantity="quantity"></shopping-cart>
</div>

<script>
Vue.component('shopping-cart', {
  props: ['quantity'],
  template: `
    <div class="shopping-cart">Quantity: {{ this.$props.quantity }}</div>
  `,
})
new Vue({   el: '#app',   data () {     return {       quantity: 3     }   } }) </script>

Here we create a component named shopping-cart which accepts one prop called 'quantity'. Inside the app we insert a instance of that component and bind the quantity from data to the prop.

Passing variables to a parent component

Often we need to pass data back to the parent component to tell it to change something. Like in this example where the shopping-cart component has a increase button. When you click it, it emits a signal back to the parent which handles the increment.

<div id="app">
  <shopping-cart :quantity="quantity" @increase="handleIncrease"></shopping-cart>
</div>

<script>
Vue.component('shopping-cart', {
  props: ['quantity'],
  template: `
    <div class="shopping-cart">
      Quantity: {{ this.$props.quantity }}
      <hr>
      <button @click="increase()">Increase</button>
    </div>
  `,
  methods: {
    increase: function() {
      this.$emit('increase');
    }
  }
})
new Vue({   el: '#app',   data () {     return {       quantity: 3     }   },   methods: {     handleIncrease: function() {       this.quantity += 1;     }   } }) </script>

If you just updated the quantity variable/prop inside the shopping-cart component the parent will never know. And if there are any other components also interacting with the quantity the prop would be overridden and the change inside the shopping-cart component will be gone.

Using an event bus

There are one more way to communicate between components and that's by using an event bus. The best part about an event bus is that you are no longen limited to child-parent communication.

Instead of using this.$emit like in the previous part you can use this.$root.$emit which is often used for this. Here is an example of how to use it:

<script>
export default {
  name: 'Cart',
  methods: {
    clickIncrease: function() {
      this.$root.$emit('clickedIncrease')
    }
  }
}
</script>

<script>
export default {
  name: 'Product',
  mounted() {  
    this.$root.$on('clickedIncrease', () => {
      console.log('increase')
    }
  }
}
</script>

this.$root.$on('clickedIncrease') can be put in any of your other components, as long as it's inside the same Vue instance.

Comments

No comments yet...

Add comment

Info

Please log in to comment!

Newsletter

Subscribe to my weekly newsletter. One time per week I will send you a short summary of the tutorials I have posted in the past week.