Reputation: 21
I want to emit event from "home" component to "about" component. But it throws this exception-"TypeError: Cannot read property '$emit' of undefined".
This is my "main.js"
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
export const bus = new Vue();
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App)
}).$mount("#app");
This is my "Home" component.
<template>
<div class="home">
<input
v-model="text"
class="text-input"
placeholder="Add text to your child component"
/>
<button @click="sendmsg" class="btn-add">Add message</button>
</div>
</template>
<script>
import { bus } from "../main";
export default {
name: "home",
data() {
return {
text: "",
};
},
methods: {
sendmsg() {
bus.$emit("msg", this.text);
this.text = "";
}
}
};
</script>
And this "About" component
<template>
<div class="about"></div>
</template>
<script>
import { bus } from "../main";
export default {
name: "about",
created() {
bus.$on("message", (data) => {
console.log(data);
});
}
};
</script>
Upvotes: 1
Views: 3815
Reputation: 21
It's working, but whem the components have their own view it's stop working.
App.vue
<template>
<div class="app">
<router-link to="/"> HOME</router-link>
<router-link to="/about"> About</router-link>
<router-view />
</div>
</template>
<style lang="scss">
.app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
align-items: center;
.btn-add {
width: 10vw;
}
.text-input {
width: 10vw;
}
}
</style>
index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue")
}
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});
export default router;
Upvotes: 0
Reputation: 165069
Looks like a race-condition brought on by a possible circular dependency (main -> App -> Home -> main).
I would suggest moving your bus
to its own module instead of main
. See here for an example
// src/event-bus.js
import Vue from 'vue'
export default new Vue()
and then in Home.vue
and About.vue
import bus from '@/event-bus'
Also, your About
component is listening for the wrong event. Home
emits "msg" but About
listens for "message". They should use the same event name.
Demo ~ https://codesandbox.io/s/serverless-frog-kvtoj?file=/src/event-bus.js
Upvotes: 1