如何使用 Vue js 2 在组件子组件链上冒泡事件?

新手上路,请多包涵

我有我的 vue 应用程序使用:

component-parent 由 component-child 组成的组件

在 component-parent 里面我有按钮,当有人点击一个按钮时我想发出一个事件以便由 vue 处理并传递给另一个组件

到目前为止我做了什么:

 var vm = new Vue({
    el: '#app',
    methods: {
        itemSelectedListener: function(item){
            console.log('itemSelectedListener', item);
        }
    }
});

Vue.component('component-child', {
    template: ' <span  v-on:click="chooseItem(pty )" >Button  </span>',
    methods: {
        chooseItem: function(pty){
            console.log(pty);
            this.$emit('itemSelected', {
                'priority' : pty
            });
        }
    }
});

Vue.component('component-parent', {
    template: '<component-child  v-for="q in items" ></component-child>'
});

HTML:

 <component-parent v-on:itemSelected="itemSelectedListener"  ></component-parent>

它到达我的 console.log(pty); 行,但似乎 this.$emit('itemSelected' 无法通过:

 console.log('itemSelectedListener', item); // this is not going to be called...

一个提示?

我应该从 child->parent->Vue-instance 冒泡事件吗? (我也尝试过但没有成功)

原文由 koalaok 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 416
2 个回答

您的 component-parent 模板存在一个问题,因为它试图呈现多个子组件。 Vue 通常需要在组件内部有一个根 div,因此您需要将其包装在 div 或其他标签中。

 <div>
    <component-child  v-for="q in items"></component-child>
</div>

要指出的第二件事是,您从一个向下 2 层的子组件发出一个事件,并在根中收听它。

 Root //but you listen to the event up here 1 level above
 Component 1 //you should listen to the event here
  Component 2 //your try to emit it from here

您在这里有 2 个选项。要么从 component-child component-parent 收听该事件,然后向上传播该事件。小提琴 https://jsfiddle.net/bjqwh74t/29/

第二种选择是注册一个名为 bus 的全局实例,这是一个空的 vue 实例,当您希望在非子父组件之间进行通信时,您可以将其用于此类情况。小提琴 https://jsfiddle.net/bjqwh74t/30/

通常在父组件和子组件之间,您直接通过从子组件发出并在父组件中监听 v-on:event-name="handler" 来使用事件,但是对于组件之间有更多级别的情况,您使用第二种方法。

第一种情况的文档链接: https ://v2.vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events

第二种情况的文档链接: https ://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

PS:更喜欢使用 kebab-case 作为事件名称,这意味着您使用 - 而不是大写字母。用大写字母书写可能会导致您的事件未在根中捕获的奇怪情况。

原文由 Cristi Jora 发布,翻译遵循 CC BY-SA 4.0 许可协议

对于它的价值,您可以使用浏览器的事件 API。它比 Vue 的内置东西需要更多的脚本,但它也可以让您解决这些冒泡问题(并且与创建“总线”的代码量大致相同,如在公认的答案中)。

在子组件上:

 this.$el.dispatchEvent(new CustomEvent('itemSelected', { detail: { 'priority' : pty }, bubbles: true, composed: true });

在父组件上,在 mounted 生命周期部分:

 mounted() {
    this.$el.addEventListener('itemSelected', e => console.log('itemSelectedListener', e.detail));
}

原文由 codeMonkey 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题