Hot questions for Using EventBus in vue component

Top 10 Java Open Source / EventBus / vue component

Question:

Here is my code in main.js

import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
import vueResource from 'vue-resource'
// import {bus } from './bus.js'
// import MainContent from './components/MainContent'

export const bus = new Vue();

Vue.config.productionTip = true

Vue.use(vueResource)
Vue.use(VueRouter)


const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    // {path:'/',component: MainContent }
  ]

})


/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})


// const bus = require('./bus.js');



var newData = new Vue({

  el: '#graph-content',
  data: {
    graphD:'',
    title: 'test title'
  },

  methods: {
    fetchData: function (data) {
    this.graphD = data;
    console.log('Inside', this.graphD);
    }
  },
  created: function () {
    bus.$on('graphdata', this.fetchData);
  }


})
console.log('OutSide', newData._data.graphD)

Answer:

You are creating 3 instances of vue, due to asynchronous of js three instances won't make sure your events working perfectly. You might layout event bus I did following code, instead using created use mounted hook

bus.js

import Vue from 'vue';
export const bus = new Vue();

main.js

import Vue from 'vue'
import App from './App'
import VueRouter from 'vue-router'
import vueResource from 'vue-resource'
import {bus } from './bus'
// import MainContent from './components/MainContent'

Vue.config.productionTip = true
Vue.use(vueResource)
Vue.use(VueRouter)


const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    // {path:'/',component: MainContent }
  ]

})


/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

var newData = new Vue({
  el: '#graph-content',
  data: {
    graphD:'',
    title: 'test title'
  },
  methods: {
    fetchData: function (data) {
      this.graphD = data;
      console.log('Inside', this.graphD);
    }
  },
  mounted: function () {
    bus.$on('graphdata', this.fetchData);
  }
})

console.log('OutSide', newData._data.graphD)

app.vue

<template>
  <div>
    <app-header></app-header>
    <app-maincontent></app-maincontent>
  </div>
</template>

<script>
  import Header from './components/Header.vue'
  import SideNav from './components/SideNav.vue'
  import MainContent from './components/MainContent.vue'
  import GraphA from './components/GraphA.vue'
  import {bus} from './bus'

  var apiURL = 'http://localhost:3000/db';
  export default {
    components: {
      'app-header': Header,
      'app-sidenav': SideNav,
      'app-maincontent': MainContent,
      'app-grapha': GraphA
    },
    data() {
      return {
        users: []
      }
    },
    methods: {
      fetchData: function () {
        var self = this;
        $.get(apiURL, function (data) {
          self.users = data;
          // console.log(data);
          bus.$emit('graphdata', "test bus");
        });

      }
    },
    mounted: function () {
      this.fetchData();
    }
  }

</script>

<style>

</style>

Instead creating many root components keep only one component and call each component as child components

Question:

I want to reload one of my components when an other component changes (for example I send a put with axios)

I tried it with eventbus but I got this error:

handler.apply is not a function

In the component where I want to trigger:

EventBus.$emit('compose-reload', Math.random()*100);

Where I want to be triggered:

<template>
    <div class="">

        <div class="">
            <div class="columns">
                <div class="column is-one-fifth">
                    <div class="box">
                        <Menu></Menu>
                    </div>
                </div>
                <div class="column is-four-fifth">
                    <div class="box">
                        <router-view :key="key"></router-view>
                    </div>
                </div>
            </div>

        </div>
    </div>
</template>
<script>
    import Menu from './includes/Menu'

    import EventBus from '../../../event-bus';

    export default {

        components: {
            Menu,
        },
        data() {
            return {
                key: null
            }
        },
        mounted(){
            EventBus.$on('compose-reload', this.key);
        },
        created(){
            this.key = Math.random()*100
        }
    }
</script>

Answer:

EventBus.$on expects a handler function as a second argument but the variable this.key is passed in, hence the error.

You should change this :

mounted(){
   EventBus.$on('compose-reload', this.key);
}

To this :

mounted(){
   EventBus.$on('compose-reload', key => {
     this.key = key;
   });
}