【问题标题】:""TypeError: Cannot read property '$emit' of undefined vue""TypeError: 无法读取未定义 vue 的属性 '$emit'
【发布时间】:2020-10-09 02:46:51
【问题描述】:

我想从“home”组件向“about”组件发出事件。但它抛出了这个异常——“TypeError: Cannot read property '$emit' of undefined”。

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

这是我的“主页”组件。

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

还有这个“关于”组件

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

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

【问题讨论】:

    标签: vue.js vue-component


    【解决方案1】:

    看起来像一个可能的循环依赖(main -> App -> Home -> 主要)。

    我建议将您的 bus 移动到它自己的模块而不是 main。示例见here

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

    【讨论】:

    • [Vue 警告]:v-on 处理程序中的错误:“TypeError:无法读取未定义的属性 '$emit'”在 ---> at src/views/Home.vue at src/App.vue TypeError: Cannot read property '$emit' of undefined
    • @DimitarIvanov 对我来说很好用。我在答案中添加了 CodeSandbox 演示
    • @DimitarIvanov 尝试按照教程和 Phil 的示例进行操作。我还重新创建了相同的代码,它工作得很好。
    • @JakubASuplicki 我也有一种有趣的感觉 OP 的代码应该可以工作,但我发现最好尽可能避免循环依赖
    • @Phil 我同意,这绝对值得指出。它们也很难测试。我相信最终,它会使应用程序更难维护。就个人而言,我起初担心文件结构,但后来他似乎遵循基线,所以应该没有问题。
    【解决方案2】:

    它正在工作,但是当组件有自己的视图时它会停止工作。

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-28
      • 2021-12-14
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 2021-06-27
      • 2019-08-04
      相关资源
      最近更新 更多