vue组件未传递事件

时间:2018-03-30 05:16:00

标签: vue.js vuejs2

我有三个嵌套组件

<parent @event="handle">
  <inbetween @event="$emit('event')">
    <child> // emits event
    </child>
  </inbetween>
</parent>

所以,当一个孩子发出这个事件时,我必须将那个恼人的部分@event="$emit('event')"添加到其间的组件中,否则父母不会收到任何事件。

我希望它不应该那样工作。我想知道它有什么问题吗?

3 个答案:

答案 0 :(得分:2)

这实际上是故意的。原因是,当查看一个组件的代码并且您看到它正在侦听事件时,您可以查看该模板以查看该事件的来源。如果事件可以任意深入到某个组件,那么就很难弄清楚该事件的触发方式和位置。

然而,Vue 曾经通过方法$broadcast$dispatch有办法做你想做的事情,并且最终因为被谈论的原因而被删除在这里。 Here's a page from the docs which explains why, along with possible solutions, such as using a global event bus, or a centralized state management solution such as Vuex.

答案 1 :(得分:2)

是的,这应该是怎么回事。事件只从孩子到父母,而不是从孩子到父母。因此,您必须从child和inbetween组件中发出事件。

如果您想避免使用此方法,可以使用事件总线:

https://medium.com/@andrejsabrickis/https-medium-com-andrejsabrickis-create-simple-eventbus-to-communicate-between-vue-js-components-cdc11cd59860

alligator.io/vuejs/global-event-bus

答案 2 :(得分:1)

Vue自定义事件不会冒泡。

在复杂情况下处理祖先/兄弟通信的推荐方法是使用Vuex。如果您有简单的需求,可以创建Vue实例以用作事件中心。

您将创建一个全局变量:

var eventHub = new Vue(); // use a Vue instance as event hub

发出您将在任何组件中使用的事件:

eventHub.$emit('myevent', 'some value');

并且,再次在任何组件中听取该事件,请执行:

eventHub.$on('myevent', (e) => {
    console.log('myevent received', e)
});

<强>演示:

var eventHub = new Vue(); // use a Vue instance as event hub

Vue.component('parent', {
    template: "#parent-tpl",
    created() {
      eventHub.$on('event', (e) => {
      	console.log('event received at parent! value:', e);
      });
    }
});
Vue.component('inbetween', {
    template: "#inbetween-tpl"
});
Vue.component('child', {
    template: "#child-tpl",
    methods: {
      emitEvent() {
        eventHub.$emit('event', 123);
      }
    }
});

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<template id="parent-tpl">
    <div>
        <inbetween></inbetween>
    </div>
</template>
<template id="inbetween-tpl">
    <div>
        <child></child>
    </div>
</template>
<template id="child-tpl">
    <div>
      <h1>I'm the child</h1>
      <button @click="emitEvent">Trigger EVENT</button>
    </div>
</template>

<div id="app">
  <p>{{ message }}</p>
  <parent></parent>
</div>

注意:如果在您的环境中创建专用实例作为事件中心是一件很复杂的事情,您可以将eventHub替换为this.$root(在您的组件中)并使用您自己的Vue实例作为集线器。