URL: https://www.progressiverobot.com/vuejs-component-communication/

There are several methods that can be used for inter-component communication in Vue.js. Normal <^>props<^> and <^>events<^> should be sufficient for most cases, but there are other methods available at your disposal as well.

Props & Events

component illustration for: Props & Events

Of course, the normal method for communication involves props and events. This common pattern provides a powerful way of communicating between components without introducing any dependency or limitations on which components are involved.

Props allow you to pass any data type to a child component, and allow you to control what sort of data your component receives. Prop updates are also reactive, allowing a child component to update whenever parent data changes.

Template Usage:

				
					
&lt;my-component v-bind:prop1="parentValue"&gt;&lt;/my-component&gt;

&lt;!-- Or more succinctly, --&gt;

&lt;my-component :prop1="parentValue"&gt;&lt;/my-component&gt;

				
			

Events provide a way to inform your parent components of changes in children.

Template Usage:

				
					
&lt;my-component v-on:myEvent="parentHandler"&gt;&lt;/my-component&gt;

&lt;!-- Or more succinctly, --&gt;

&lt;my-component @myEvent="parentHandler"&gt;&lt;/my-component&gt;

				
			

Firing an Event:

				
					
...

export default {

  methods: {

    fireEvent() {

      this.$emit('myEvent', eventValueOne, eventValueTwo);

    }

  }

}

				
			

Additionally, you can create global event buses to pass events anywhere in your app. We've got an article on that.

Combined:

Using v-model allows for combining props with events for two-way binding. This is often used for input components. <^>v-model<^> assumes the <^>value<^> prop and <^>input<^> event, but this can be customized.

Template Usage:

				
					
&lt;my-component v-model="prop1"&gt;&lt;/my-component&gt;

				
			

A v-model compatible component:

				
					
&lt;template&gt;

  &lt;div&gt;

    &lt;input type="text" :value="value" @input="triggerEvent"/&gt;

  &lt;/div&gt;

&lt;/template&gt;



&lt;script&gt;

  export default {

    props: {

      value: String

    },



    methods: {

      triggerEvent(event) {

        this.$emit('input', event.target.value);

      }

    }

  }

&lt;/script&gt;

				
			

Use When: You need to do pretty much any sort of data passing and messaging between components.

Provide / Inject

A much newer addition to <^>Vue<^> is the provide / inject mechanism. It allows for selective exposition of data or methods from an ancestor component to all of its descendants. While <^>provide / inject<^> is not itself reactive, it can be used to pass reactive objects.

<^>provide / inject<^> is probably not a good idea to develop an app with, but it can come in quite handy when writing whole custom-rendered component libraries.

Ancestor Component:

				
					
const SomethingAllDescendantsNeed = 'Air, probably.';



export default {

  provide: {

    SomethingAllDescendantsNeed

  }

}

				
			

Descendant Component(s):

				
					
export default {

  inject: ['SomethingAllDescendantsNeed'],



  mounted() {

    console.log(this.SomethingAllDescendantsNeed);

  }

}

				
			

Template Usage:

				
					
&lt;ancestor-component&gt;

  &lt;div&gt;

    &lt;descendant-component&gt;

      &lt;p&gt;

        &lt;descendant-component&gt;&lt;/descendant-component&gt;

      &lt;/p&gt;

    &lt;/descendant-component&gt;

  &lt;/div&gt;

&lt;/ancestor-component&gt;

				
			

(All descendant components, no matter how deep in the tree, have access to <^>SomethingAllDescendantsNeed<^>.)

Use When: Child components need access to an instance of something that's only instantiated once per component tree. (Perhaps another library or an event bus.)

Direct Access

CAUTION: HERE BE SHARKS!

If you really, really, really, neeeeed to access a property or method directly on a parent or child component, you can use every component's <^>this.$parent<^> and <^>this.$children<^> properties to have full access to everything on parent and children components. This is, however, and absolutely, horribly, despicably, terrible idea. If you find yourself in a situation where you need to do this, there's a <^>99.99958%<^> chance you did something wrong and should refactor.

Use When: DON'T. JUST DON'T.

Why not? Because you are introducing a direct coupling between both the implementation and structure in markup between parent and children components, making them inflexible and ridiculously easy to break.