【问题标题】:In Vue - how can I trigger a broadcast to pick up event in a different control?在 Vue - 我如何触发广播以在不同的控件中获取事件?
【发布时间】:2025-11-23 10:20:14
【问题描述】:

我有一个步骤组件,当我单击下一步按钮时,我需要在我的步骤组件中触发一个事件。

这个事件应该被另一个组件接收,它代表当前步骤中页面的内容。

这是我尝试过的:

步骤组件模板:

<template>
  <div class="steps">
    <div class="steps-content">
      <section class="steps-panel" v-for="(stepPage, index) in steps">
        <header class="posA wrap pTs">{{$t(title)}}</header>
        <component :is="stepPage">
           <!-- Summary component is injected here -->
        </component>
      </section>
    </div>
    <div role="navigation">
      <ol class="fixed nav nav--block steps-nav w100">
        <li class="steps-label txtCap" v-for="(stepPage, index) in steps">
          {{$t(stepPage.name)}}
        </li>
      </ol>
      <button class="steps-button" type="button">
        <i class="pf pf-arrow-left"></i>
        <span class="steps-button-label">{{$tc('previous')}}</span>
      </button>
      <button class="steps-button" type="button" v-on:click="next">
        <span class="steps-button-label">{{$tc('next')}}</span>
        <i class="pf pf-arrow-right"></i>
      </button>
    </div>
  </div>
</template>

Steps组件方法:

methods: {
  next(event) {
    console.log('emit stepnext')
    this.$emit('stepnext')
  }
}

我在步骤模板中使用v-on:click="next" 调用它(在“下一步”按钮上) 从console.log看到执行了click事件,$emit调用没有触发任何错误,所以此时似乎可以正常工作了。

摘要组件

摘要组件是“步骤”中的组件之一,由步骤模板中的此条目加载:

<component :is="stepPage"></component>

在知道单击此按钮时该做什么的摘要组件中,我尝试通过在模板中包含此事件来获取此事件:

<div class="wrap" v-on:stepnext="stepfinish">
 ... content ...
</div>

... 以及一个名为 stepfinish 的摘要组件中的方法执行该操作,但发出的事件似乎永远不会到达我的摘要组件。

我该如何解决这个问题?

【问题讨论】:

  • 你能用小提琴或codepen演示这个问题吗?
  • 我添加了一些关于结构的更多细节。这应该足以理解问题。

标签: vuejs2


【解决方案1】:

使用$root时的简单解决方案:

// trigger
this.$root.$emit('my-event');

// listen
this.$root.$on('my-event');

【讨论】:

    【解决方案2】:

    我认为您正在寻找event bus 以下是官方文档中的一些 sn-p:

    var bus = new Vue()
    
    // in component A's method
    bus.$emit('id-selected', 1)
    
    // in component B's created hook
    bus.$on('id-selected', function (id) {
      // ...
    })
    

    链接:https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

    这里有一篇关于相同的博客:https://alligator.io/vuejs/global-event-bus/

    【讨论】:

    • 是的,我也在考虑这个问题,但是从 vue 指南中很难弄清楚如何在任何组件中使其全局可用。您共享的另一个链接完美地解释了这一点。谢谢! :)
    • 鳄鱼链接非常好理解
    【解决方案3】:

    如果你完全想解耦你的组件,或者你想跨 Vue“应用程序”和/或不同的框架(React,...)进行通信,那么你也可以使用 DOM Native 事件:

          document.dispatchEvent(
            new CustomEvent("myapp:someClick", {
              detail: {
                id: 1,
                someMoreCustomPayload: "bar",
              },
            })
          )
    

    在接收方方面:

        document.addEventListener("myapp:someClick", (ev) => {
          const { id, someMoreCustomPayload } = ev.detail
          ...
        })
    

    IE11 也可以处理 CustomEvents 但显然不支持detail,但可以是polyfilled

    【讨论】:

      最近更新 更多