I use webpack with Single File Component.
I have 1 instance of Vue in my menu header to show a Cart Shopping dropdown :
import Vue from 'vue';
import App from './AppShoppingCart.vue';
new Vue({
el: '#shoppingCartApp',
template: '<App/>',
components: {App}
});
I have an other Vue instance in the same page (the catalog with products) :
import Vue from 'vue';
import App from './AppCatalog.vue';
new Vue({
el: '#catalogApp',
template: '<App/>',
components: {App}
});
I want to $emit an event from one instance to the other : when Catalog change, I want to call a function in ShoppingCart.
I test eventHub :
import Vue from 'vue';
var eventHub = new Vue();
export default eventHub;
So I import event on each instance :
import eventHub from './events/eventHub';
In Catalog :
eventHub.$emit( "actproductslist-changed" );
In ShoppingCart :
eventHub.$on('actproductslist-changed', function(){ alert('AppShoppingCart') } );
But this won't works. It only works if the $on and $emit are in the same instance of Vue.
I think webpack create 2 modules and I can't share variables between my 2 instances.
This setup works, where main.js
is your entry point.
bus.js
import Vue from "vue"
const bus = new Vue();
export default bus;
main.js
import Vue from 'vue'
import App from './App.vue'
import App2 from './App2.vue'
new Vue({
el: '#app',
render: h => h(App)
})
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
methods:{
sendMessage(){
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
import bus from "./bus"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
To communicate across entry points, you can expose the bus
Vue on the window.
webpack.config.js
entry: {
"main": './src/main.js',
"main2": './src/main2.js'
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: '[name].js'
},
bus.js
import Vue from "vue"
window.bus = new Vue();
main.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
main2.js
import Vue from 'vue'
import App2 from './App2.vue'
import bus from "./bus"
new Vue({
el:"#app2",
render: h => h(App2)
})
App.vue
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
import Vue from "vue"
export default {
methods:{
sendMessage(){
if (bus)
bus.$emit("testing")
}
}
}
</script>
App2.vue
<template></template>
<script>
import Vue from "vue"
export default {
mounted(){
bus.$on("testing", ()=> alert("message received"));
}
}
</script>
Note here that since bus
is only imported in main2.js
, you need to guard the use of it in App.vue
for those cases where it might not exist (because it is only imported in main2.js
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With