title: VueJS 2.0 - Communication Between Sibling Components - $emit and $on
body: <p>I am building out an app as follows.. Let's look at one model I'm using.. (I've got Laravel 5.3 in the background just serving up the basic views and serving the API.</p>
  <p>For example: Clients.<br />
  at example.com/admin/clients I load two components <code>&lt;admin-clients-moderator&gt;</code> and <code>&lt;admin-clients-navigator&gt;</code>. The Moderator is a form to modify the currently selected Client. The Navigator is to navigate and select the client you wish to operate on.</p>
  <p>These are both loaded in as global components into the root Vue, <code>#admin-app</code>.</p>
  <p>In Vue.js 1.0, I had the root instance load the two components with <code>:selected-client.sync=&quot;selectedClient&quot;</code> which was tied to a root data variable <code>&quot;selectedClient&quot;</code> and these components accepted <code>&quot;selectedClient&quot;</code> as props and when the Navigator chose a new client, the navigator would update <code>selectedClient</code>, and since it is passed by reference, this would update the root instance and thus the synced Moderator too and then the form would populate with the details for that client.</p>
  <p>When the form was cancelled/saved, I <code>$broadcast</code> an event from the components <code>$parent</code>, so that the sibling would be able to act on it in the 'events'...</p>
  <p>I am trying to replicate this functionality in Vue.js 2.0 but have been unable to.</p>
  <p>I have read the documentation on updating from 1.0 to 2.0, but they warn against the mutation of props that I've been using, and I've been unable how to figure out how exactly they setup the <code>$emit</code> and <code>$on</code> functions using the <code>eventHub</code> as they outlined.</p>
  <p>I wouldn't mind using that <code>eventHub</code> example, but need more direction on how to implement it...</p>
  <ul>
  <li>Can I use <code>$on</code> in my sibling component?</li>
  <li>Do I need to define this separately in each root instance?</li>
  <li>Should I have a different root instance for each model I'm working on?</li>
  <li>Is there a vue extension/plugin that would be suited for this?</li>
  <li>Am I even approaching this the right way?</li>
  </ul>
  <p><strong>Code snippets below</strong></p>
  <p><strong>My app.js</strong></p>
  <pre><code>Vue.component(
      'admin-clients-moderator',
      require('./components/admin/clients/Moderator.vue')
  );
  
  Vue.component(
      'admin-clients-navigator',
      require('./components/admin/clients/Navigator.vue')
  );
  
  var mainApp = new Vue({
      el: '#app',
      data: {
          selectedClient: {}, // I don't think i need this anymore
      }
  });
  </code></pre>
  <p><strong>My Navigator.vue (simplified)</strong></p>
  <pre><code>.... Template ....
          &lt;tr v-for=&quot;client in collection&quot;&gt;
              &lt;td&gt;{{ client.name }}&lt;/td&gt;
              &lt;td&gt;{{ client.status }}&lt;/td&gt;
              &lt;td&gt;
                  &lt;button class=&quot;btn btn-primary btn-xs&quot;
                          @click=&quot;select(client)&quot;
                  &gt;
                      &lt;i class=&quot;fa-search fa&quot;&gt;&lt;/i&gt;
                  &lt;/button&gt;
  
                  &lt;button class=&quot;btn btn-danger btn-xs&quot;
                          @click=&quot;remove(client)&quot;
                  &gt;
                      &lt;i class=&quot;fa-trash fa&quot;&gt;&lt;/i&gt;
                  &lt;/button&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
  
  .... Javascript ....
  
  &lt;script&gt;
  export default {
      props: [],
      data() {
          return {
              selectedClient: {},
              collection: [],
              // TRAIT
              resource: null,
              resourceUri: &quot;&quot;,
              modelName: &quot;&quot;
          };
      },
      methods: {
          select(client) {
              this.$emit('client-selected', {client});
              this.selectedClient = client;
          },
          remove(client) {
              this.deleteModel(client)
          },
  </code></pre>
  <p><strong>Moderator.vue</strong></p>
  <pre><code>.... JaveScript
  
  
  &lt;script&gt;
  export default {
      props: [],
      data() {
          return {
              selectedClient: {},
              // TRAIT
              resource: null,
              resourceUri: &quot;&quot;,
              modelName: &quot;&quot;
          };
      },
      computed: {
          newClient() {
              return (this.selectedClient.id == null
              || this.selectedClient.id == 0);
          }
      },
      created() {
          this.$on('client-selected', this.setSelectedClient);
      },
      methods: {
          setSelectedClient(client) {
              this.selectedClient = client;
          },
  </code></pre>