You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue动态组件中Event Bus无法正常工作的问题排查

Vue Event Bus 动态组件通信问题解决

我来帮你捋清楚这个问题的根源,以及对应的解决办法~

问题核心原因

你遇到的关键问题是事件触发时机和组件实例化时机不匹配:
当你在Test1Component点击按钮时,先执行this.$emit("changeComponent")切换组件,紧接着就触发this.$bus.$emit("test")。但Vue切换动态组件需要经历「销毁旧组件→创建新组件→挂载新组件」的异步过程——也就是说,当$bus.$emit("test")执行时,Test2Component还没被创建出来,它的created钩子还没执行,自然没注册上事件监听器,所以根本听不到这个事件。

而HomeComponent的监听器是在自身created钩子中注册的,从页面加载时就存在,所以能正常监听到事件。

另外还要提个小细节:你main.js里的Vue.propotype拼写错了,应该是Vue.prototype,虽然这个可能没影响当前功能,但修正后更规范。

解决方案

这里给你两种靠谱的解决思路:

方案1:延迟触发总线事件,等Test2Component创建完成后再发

把总线事件的触发时机放到组件切换完成之后,利用Vue的$nextTick确保新组件已经挂载完成:

  1. 修改Test1Component的方法,只负责触发组件切换:
<script>
export default {
  methods: {
    changeComponent() {
      this.$emit("changeComponent");
      // 移除这里的 this.$bus.$emit("test")
    }
  }
};
</script>
  1. 在HomeComponent的切换方法中,用$nextTick延迟触发总线事件:
<script>
import Test1Component from "./Test1Component";
import Test2Component from "./Test2Component";

export default {
  // ...其他代码不变
  methods: {
    changeComponent() {
      this.currentComponent = "Test2Component";
      this.$nextTick(() => {
        // 等Test2Component创建挂载完成后再触发事件
        this.$bus.$emit("test");
      });
    }
  }
};
</script>

方案2:改用组件props传递(适合简单场景)

如果只是在组件切换时传递状态或触发通知,也可以不用Event Bus,直接通过动态组件的props传递信息:

  1. HomeComponent中添加状态,传递给Test2Component:
<template>
  <div>
    <component 
      :is="currentComponent" 
      @changeComponent="changeComponent"
      :triggerTest="triggerTest"
    ></component>
  </div>
</template>

<script>
// ...其他代码不变
export default {
  data() {
    return {
      currentComponent: "Test1Component",
      triggerTest: false
    };
  },
  methods: {
    changeComponent() {
      this.currentComponent = "Test2Component";
      this.$nextTick(() => {
        this.triggerTest = true;
        // 如果需要只触发一次,之后可以重置
        setTimeout(() => this.triggerTest = false, 0);
      });
    }
  }
};
</script>
  1. Test2Component监听props变化:
<script>
export default {
  props: ['triggerTest'],
  watch: {
    triggerTest(newVal) {
      if (newVal) {
        console.log("test in test2");
      }
    }
  }
};
</script>

验证效果

按照方案1修改后,Test2Component就能正常输出test in test2了,因为此时事件触发时,Test2的监听器已经注册完成。

内容的提问来源于stack exchange,提问作者ChenLee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:54:36