Open In App

Communication between components using $emit and props in Vue.js

Last Updated : 12 Dec, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Components in Vue.js need to share data with each other sometimes in order to give the desired output. Components in a webpage are in a hierarchical order like a tree. The most basic way of interacting and passing data between components is using $emit and props.

$emit and props: In Vue.js, we use $emit to generate custom events for our component. Meaning just like a mouse click or scrolling generates an onclick and onwheel events we can generate events from our component methods and name them according to our convention. Not only this, we can also pass data as arguments to this event.

this.$emit('setevent',someVariable);

Props are used to pass data to components as custom attributes. Props are added to components as follows –

Vue.component('exampleComponent',{
    props: ['sometext'],
    
    template : `<p>This is the prop data - {{sometext}}</p>`

});

How does it work? 

So how this works is parent component listens to the event of first child component and then executes a method band to it. This method gets the data of the event as an argument and then passes on this data to props of the second child component.

Example: The following example illustrates how this mechanism works. It’s a very basic webpage which displays how many times a button has been clicked. It has 3 components – A parent component and 2 child components within it.

HTML




<!DOCTYPE html>
<html>
 
<head>
    <meta charset="utf-8">
    <meta name="viewport" content=
        "width=device-width, initial-scale=1">
 
    <!-- Including Vue using CDN-->
    <script src=
    </script>
 
    <!-- Javascript code -->
    <script src="script.js"></script>
     
    <style>
        .component1 {
            display: block;
            background-color: green;
            height: 15em;
            text-align: center;
            color: white;
            padding-top: 5em;
        }
         
        .component2 {
            display: block;
            background-color: grey;
            height: 15em;
            text-align: center;
            padding-top: 5em;
        }
    </style>
</head>
 
<body>
    <div id="root">
        <parentcomponent></parentcomponent>
    </div>
</body>
 
</html>


Javascript




/* First component has a heading element in
   the template which shows how many times
   the button in 2nd component has been
   clicked. It uses props. */
Vue.component('component1', {
    props: ['labeltext'],
 
    // This props is then used in template
    // to have dynamic values.
    template: `<div class="component1">
    <h1>You have clicked {{labeltext}} times</h1>
    </div>`
});
 
/* Second component has a button which when
clicked upon executes the count method. A
custom event namely ‘setevent’ is triggered
by this method. */
Vue.component('component2', {
    data() {
        return {
            nclick: 0
        }
    },
    template: `<div class="component2">
        <button @click = "count">Click</button>
        </div>`,
    methods: {
        count() {
            this.nclick += 1;
 
            // Emitting a custom-event
            this.$emit('setevent', this.nclick);
        }
    }
});
 
// This is just a div element component which
// contains the two child components in it.
Vue.component('parentcomponent', {
    data() {
        return {
            text: 0
        }
    },
 
    // Set method is binded to the 'setevent'
    // event and labeltext is the prop.
    template: `<div>
        <component1 :labeltext = "text"></component1>
        <component2  @setevent = "set"></component2>
    </div>`,
    methods: {
        set(n) {
 
            // Updates the variable text which
            // is the value of prop attribute
            this.text = n;
        }
    }
});
 
new Vue({
    el: '#root',
    data: { }
})


Output:

Applications and scope: Components in a Vue.js web app are in a hierarchical order with many levels like a tree with components inside components. Using above method, it is possible to chain multiple events and climb up this tree and then pass on data to below levels using prop.

Hence, this method is very suitable when we require component interaction within 2 or 3 levels but as soon as our web app requires interaction among components which are on very different levels this process becomes increasingly complex as you can imagine. That’s when state management libraries like Vuex come into play. But for basic interactions we use $emit and props, so as not to chuck every little thing into our Vuex store.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads