Search code examples
javascriptvuejs2vue-componentevent-bus

How to get data in Main.js from App.vue in Vue js?


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)

Here is the bus emit data from app.vue

bus.$emit('graphdata', "test bus");

Using following code I am trying to get data from app.vue. I am getting data inside the scope of fetchData but I am not getting from outside of newData scope. Could anyone suggest me where is the problem or possible solution to pass data/object from app.vue to main.js file.

****Updated ***** 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 './main.js'

  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");
    });

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

</script>

<style>

</style>


Solution

  • 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