使用$emit在两个Vue实例间通信时$on未被触发的问题
问题原因
- Vue实例的
$emit、$on方法是实例私有的,仅在当前实例内部生效:你在主实例模板中触发的toggle_dm事件,只有主实例自身通过$on监听才能收到,darkmode作为独立的另一个实例,默认无法接收其他实例触发的私有事件。 - 模板中不需要额外加
this,你写this.$emit报错属于模板上下文识别异常的次要问题,核心故障是事件通信的对象错配。
解决方案
方案1:直接调用目标实例方法(最适合当前简单场景)
因为你已经把darkmode实例声明为全局变量,直接在主实例的点击事件中调用它的切换方法即可,不需要走事件通信:
<svg v-on:click="darkmode.toggle_light_scheme()" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 250 250" x="0px" y="0px"> <!-- 其余svg内容保持不变 --> </svg>
修改后直接删除darkmode实例中mounted里的$on监听逻辑即可,实现更简洁。
方案2:使用公共事件总线(适合多实例多事件通信的复杂场景)
如果后续有更多跨实例通信需求,可以新建一个空Vue实例作为中央事件总线:
- 全局声明总线实例:
const eventBus = new Vue()
- 修改主实例的点击触发逻辑:
<svg v-on:click="() => eventBus.$emit('toggle_dm')" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 250 250" x="0px" y="0px"> <!-- 其余svg内容保持不变 --> </svg>
- 修改darkmode实例的监听逻辑,改为监听总线的事件:
mounted(){ eventBus.$on("toggle_dm", ()=> { alert("message received") // 也可以直接调用this.toggle_light_scheme()完成切换 }); }
内容的提问来源于stack exchange,提问作者ORStudios
相关产品推荐
相关产品推荐

