开发者问题收集

“”TypeError:无法读取未定义 vue 的属性‘$emit’

2020-06-18
3621

我想从“home”组件向“about”组件发出事件。但是它抛出了此异常 - “TypeError:无法读取未定义的属性‘$emit’”。

这是我的“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");

这是我的“Home”组件。

<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>

还有这个“About”组件

<template>
  <div class="about"></div>
</template>

<script>
import { bus } from "../main";
export default {
  name: "about",
  created() {
    bus.$on("message", (data) => {
      console.log(data);
    });
  }
};
</script>
2个回答

看起来像是由可能的循环依赖 ( main -> App -> Home -> main ) 引起的竞争条件。

我建议将您的 bus 移至其自己的模块,而不是 main 。请参阅 此处 获取示例

// src/event-bus.js
import Vue from 'vue'
export default new Vue()

然后在 Home.vueAbout.vue

import bus from '@/event-bus'

此外,您的 About 组件正在监听错误的事件。 Home 发出 “msg” ,但 About 监听 “message” 。它们应该使用相同的事件名称。

演示 ~ https://codesandbox.io/s/serverless-frog-kvtoj?file=/src/event-bus.js

Phil
2020-06-18

它可以工作,但是当组件有自己的视图时它就停止工作了。

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;
Dimitar Ivanov
2020-06-19