Search code examples
vue.jsevent-bus

Communicate between two components(not related with child-parent)


component 1

 getMyProfile(){    
       this.$root.$emit('event');
           console.log("emited")
     }, 

component 2

mounted() {
    this.$root.$on('event', () = {
    alert("Fired");
 }
}

I am trying to alert "fired" of comonent 2 from component 1. But this is not happening. what i am doing wrong. Should i have to add something on main js?


Solution

  • Other than the small typo in your $on, it's not clear what you're doing wrong, as you haven't provided enough context, but here's a working example of exactly what you're trying to do (send and receive an event via the $root element, without instantiating a separate eventbus Vue instance). (Many people do prefer to do the message passing via a separate instance, but it's functionally similar to do it on $root.)

    I included a payload object to demonstrate passing information along with the event.

    Vue.component('sender', {
      template: '<span><button @click="send">Sender</button></span>',
      methods: {
        send() {
          console.log("Sending...")
          this.$root.$emit('eventName', {
            message: "This is a message object sent with the event"
          })
        }
      }
    })
    
    Vue.component('receiver', {
      template: '<span>Receiver component {{message}}</span>',
      data() {return {message: ''}},
      mounted() {
        this.$root.$on('eventName', (payload) => {
          console.log("Received message", payload)
          this.message = payload.message
        })
      }
    })
    
    new Vue({
      el: '#app'
    });
    <script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
    <div id="app">
      <sender></sender>
      <receiver></receiver>
    </div>

    Personally I don't tend to use this pattern much; I find it's better to handle cross-component communication from parent to child as props, and from child to parent as direct $emits (not on $root). When I find I'm needing sibling-to-sibling communication that's generally a sign that I've made some poor architecture choices, or that my app has grown large enough that I should switch over to vuex. Piling all the event messaging into a single location, whether that's $root or an eventbus instance, tends to make the app harder to reason about and debug.

    At the very least you should be very explicit in naming your events, so it's easier to tell where they're coming from; event names such as "handleClick" or just "event" quickly become mysterious unknowns.