"" TypeError: невозможно прочитать свойство '$ emit' неопределенного vue - PullRequest
0 голосов
/ 19 июня 2020

Я хочу передать событие из компонента «home» в компонент «about». Но он выдает это исключение - «TypeError: невозможно прочитать свойство '$ 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");

Это мой «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>

А этот компонент «О программе»

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

1 голос
/ 19 июня 2020

Похоже на состояние гонки, вызванное возможной циклической зависимостью ( main -> App -> Home -> main ).

Я бы посоветовал перенести ваш bus в отдельный модуль вместо main. См. здесь для примера

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

, а затем Home.vue и About.vue

import bus from '@/event-bus'

Кроме того, ваш About компонент прослушивает неправильное событие. Home выдает "msg" , но About прослушивает "сообщение" . Они должны использовать одно и то же имя события.

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

0 голосов
/ 19 июня 2020

Работает, но если компоненты имеют собственное представление, это перестает работать.

Приложение. 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;
...