Vue components communication

In addition to pesla' answer take a look at the guide's State Management section under Building large scale apps: http://vuejs.org/guide/application.html#State_Management . I've created a jsfiddle based on that here: https://jsfiddle.net/WarwickGrigg/xmpLg92c/.

This technique works for components too: parent-child, sibling-sibling component relationships etc.

var hub = {
  state: {
    message: 'Hello!'
  }
}

var vmA = new Vue({
    el: '#appA',
    data: {
      pState: {
        dA: "hello A" 
    },
    hubState: hub.state
  }
})

var vmB = new Vue({
    el: '#appB',
    data: {
      pState: {
        dB: "hello B"
    },
    hubState: hub.state
  }
})

Cross-component communication doesn't get much attention in the Vue.js docs, nor are there many tutorials that cover this subject. As components should be isolated, you should never "access" a component directly. This would tightly couple the components together, and thats exactly what you want to prevent doing.

Javascript has an excellent method for communication: events. Vue.js has a built-in event system, mainly used for parent-child communication. From the docs:

Although you can directly access a Vue instance’s children and parent, it is more convenient to use the built-in event system for cross-component communication. It also makes your code less coupled and easier to maintain. Once a parent-child relationship is established, you can dispatch and trigger events using each component’s event instance methods.

Their example code to illustrate the event system:

var parent = new Vue({
  template: '<div><child></child></div>',
  created: function () {
    this.$on('child-created', function (child) {
      console.log('new child created: ')
      console.log(child)
    })
  },
  components: {
    child: {
      created: function () {
        this.$dispatch('child-created', this)
      }
    }
  }
}).$mount()

Dan Holloran has recently written a piece on his "struggle" with cross-component messaging, in two pieces. This might be helpful to you if you need communication between components that have no parent-child relationship.

Another approach I have experience with (other than using events for communication), is using a central component registry that has a reference to the public API with an instance of a component bound to it. The registry handles requests for a component and returns its public API.

In the context of Vue.js, events would by my weapon of choice.


Communication between the components can also be established by creating a single global event hub in your Vue application. Something like this:-

var bus = new Vue();

Now you can create custom events and listen to them from any component.

     // A.vue
    // ...
    doThis() {
        // do the job
    
        bus.$emit('done-this');
    }
    
    // B.vue
    // ...
       method:{
             foo: function()
          }
    created() {
        bus.$on('done-this', foo);
    }

More about this can be found from official documentation..


It's best practice to use props and events.

There are many examples online, like:

  • https://v2.vuejs.org/v2/guide/components.html
  • https://alligator.io/vuejs/component-communication

I recommend some reading on the topic.

If the components are siblings and have no parent-child relationship it might be worth checking the architecture of your app.

  • Do A and B have a parent child relationship?
  • Is there a component C that is possibly the parent of A and B?

If A and B are children of C, consider using props and events. Another way is to use props and sync, which can be helpful for form data:

  • https://medium.com/front-end-hacking/vues-v-model-directive-vs-sync-modifier-d1f83957c57c