How to share data across components in Vue

Since the dawn of days and the beginning of mankind, man has been plagued with the inability to communicate and this is nonetheless short in computer and programming

Some of the problems we all run into - both beginners and experienced - while writing different components on any Frontend framework is "how do I share data between these components and also with the parent"

In this article, I would like to talk specifically about the front-end framework , Vue.js because Thanks to Evan you, it's the most simplest yet powerful Frontend framework to quickly familiarise with as a beginner.

With that said, There are multiple ways to communicate between components in Vue.js. They are

  1. Using PROPS
  2. Using Event
  3. Using Event Bus to communicate between any component
  4. Using State Management

1. Using Props

"Props" are custom attributes you can register on a component, that enable us to pass data and functions from one component to another.

<template>
  <h1> Hello Vue </h1>
  <BlogPost title="My journey with Vue" />
</template>

It's important to understand that props data-flow is one directional - we can pass data only from a parent to a child component, not another way around. When a value is passed to a prop attribute, it becomes a property on that component instance. To pass a title to our blog post component, we can include it in the list of props this component accepts, using a props option:

  export default {
     props: {
        title: String,
        likes: Number
      }
    }

  // OR WITH ARRAYS

export default {
     props: [ "title", "likes"]
    }

Learn More On Props here

Earlier, we mentioned creating a component for blog posts. The problem is, that component won’t be useful unless you can pass data to it, such as the title and content of the specific post we want to display. That’s where props come in.

Go and create a component called Parent component (Parent.vue)

// Parent component
  <template>  
     <div>  
        <h1>News Headline </h1>
        <BlogPost 
          title="My Journey with Vue" 
          date="April, 2022" 
          likes="100" 
          nameOfAuthor="TechSupport ❤️" 
        />
     </div>  
  </template>  
  <script>  
     // Path of child component  
     import BlogPost from "./blogPost.vue";  
     export default {  
        name: 'Parent',  
        components: {  
           BlogPost
        }  
     }  
  </script>

NOTE: For passing data from parent component to child component, we need to create parent component file and inside parent component, we need to import child component and add child component tag as () and here we are passing data to child component as “title”, etc..

// *child component*
  <template>  
     <div>  
        <h1>{{ nameOfAuthor }}</h1>  
     </div>  
  </template>  
  <script>  
  export default {  
     name: 'Child',  
     props: [  
       // camelCase in JavaScript  
       'title',
       'date',    
       'likes',
       'nameOfAuthor' 
     ]  
  }  
  </script>

<style lang="scss" >
  /* --- */
</style>

RESULT : Screenshot 2022-08-16 at 02-54-26 % htmlWebpackPlugin.options.title %.png

Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property on that component instance.

2. Emitting Events

Right now I'm going to show you How we can pass data from "child component to parent component."

For this, we need to emit an event.

For illustration,

Step 1

Go and create Child component (Child.vue)

    <template>  
       <div class="submit-btn">  
          <p>  
             <input type="submit" value="Submit"           @click="callingParentComponentMethod">  
             <!-- "OR" -->  
             <input type="submit" value="Submit" v-on:click="callingParentComponentMethod">  
          </p>  
       </div>  
    </template>  
    <script>  
    export default {  
       name: "Child",  
       methods: {  
          // This method will call on click of submit button  
          callingParentComponentMethod() {  
          // emit the event and call the parent component  
          this.$emit("setParentComponentDetails");  
          }  
       }  
    };  
    </script>    

    <style lang="scss" >
      /* --- */
   </style>

NOTE : In template section, We are calling method “callingParentComponentMethod” on submit click.

You can call method in two way like @click or v-on:click .

Inside Script section, we are using “this.$emit()” method to call parent component.

You can pass some parameter from child component to parent component, below are the examples:

 this.$emit("setParentComponentDetails", param1, param2);

STEP 2

Go and create parent component (Parent.vue)

<template>  
   <div>  
      <Child @setParentComponentDetails="setDetailsForComponent" > </Child>  
   </div>  
</template>  
<script>  
// Path of child component  
import { Child } from "./child.vue";  
   export default {  
   name: 'Parent',  
   components: {  
      Child  
   },  
   methods: {  
      // Called by child component  
      setDetailsForComponent() {  
      console.log("Calling from child component");  
      }  
   }  
}  
</script>

<style lang="scss" >
  /* --- */
</style>

NOTE: In template section, We are setting event(“setParentComponentDetails”) which is sent by child component and called method(“setDetailsForComponent()”) inside script section.

Scenario

If you are getting some parameter from child component then you can receive these parameter in parent component inside method section like,

setDetailsForComponent(param1, param2){  
   Console.log(param1 + '' + param2);  
}

3. Using Event Bus to communicate between any component

Originally, We need to understand what's the meaning of no relationship between component. It’s means when two sibling components( no parent --> child relationship) are communicated, so on that time we can use EVENT BUS publish

We can use Event Bus on veritably simplest architecture. It allow us to emit an event in one component and listen for that event in another component. Below are the several step to get this communication,

Step 1 — Initialization of EVENT BUS

Create a file ‘event-bus.js’ and write below code

import Vue from 'vue';  
export const EventBus = new Vue();

Step 2 — Using the Event bus

We have created the event bus, now we need to import in our component.

import { EventBus } from "./event-bus.js";

Step 3 — Sending Event from component

We need to emit an event whenever someone click on button.

Create new component ‘component1.vue’ and write below code:-

<template>  
   <div class="click-me">  
      <button @click="emitGlobalClickEvent">Please Click me</button>  
   </div>  
</template>  
<script>  
// Import the EventBus we just created.  
import { EventBus } from "./event-bus.js";  
   export default {  
   name:'component1',  
   data() {  
   return {  
      Count: 0  
   };  
},  
methods: {  
emitGlobalClickEvent() {  
   this.Count++;  
      // Send the event on a channel (i-got-clicked) with a payload (the click count.)  
      EventBus.$emit("clicked-event", this.Count);  
      }  
   }  
};  
</script>

<style lang="scss" >
  /* --- */
</style>

NOTE : Here we are setting Event “clicked-event” which will be use as receiving event in other component

Step 4 — Receiving/Listening Event

We need to listen an event using Event.$on.

Create new component ‘component2.vue’ and write below code:-

<script>  
// Import the EventBus.  
import { EventBus } from "./event-bus.js";  
export default {  
   name: 'Component2',  
   mounted() {  
   // Listen for the 'clicked-event' and its payload.  
      EventBus.$on("clicked-event", Count=> {  
      console.log(`Oh, that's great. It's gotten ${Count} clicks! :)`);  
      });  
   }  
};  
</script>

NOTE: Here we are listening Event “clicked-event” inside life cycle hook ‘mounted’.

ALTERNATIVE OPTION :-

Sometimes you will get some complex scenario, so on that time we have an option to use Vuex or any third party libraries.

I hope you find this article really helpful, Let me know what you think.

Thanks for reading ❤️ and Happy learning ❤️🎈 photo-collage.png