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

Vue组件事件监听疑问:非父组件能否监听触发的事件?

Vue组件跨组件事件监听的疑问

我正在学习Vue.js,之前了解到子组件向父组件传递数据时,会使用this.$root.$emit('name-of-event', myobject);,父组件则通过this.$root.$on('name-of-event');接收事件。

但在一个用于对比学习的Vue.js项目中,我发现监听事件的组件并非触发事件组件的父组件(触发事件的组件标签并未在监听组件的模板中渲染)。

我的问题:是否必须由直接父组件监听触发的事件?其他组件能否监听触发的事件?


myAcomponent.vue:

updateDate(value) {
    // updateDate方法内容
    this.$root.$emit('date-updated', this.project);
}

myBcomponent.vue:

<template>
    <!-- 模板中未调用myAcomponent -->
</template>

<script>
    created() {
        this.$root.$on('date-updated', project => {
            this.updateproject(project);
        });
    }
</script>

解答

不是必须由直接父组件监听触发的事件,其他组件完全可以监听——关键在于你这里用了$root作为全局事件总线。

具体说明:

  • 当你通过this.$root.$emit触发事件时,这个事件是绑定在根Vue实例上的,整个应用里所有能访问到$root的组件,不管有没有直接父子关系,都能通过this.$root.$on监听该事件。
  • 你之前了解的“子组件向父组件传数据”的常规场景,一般是用组件自身的$emit(而非$root.$emit),这时事件会沿组件树向上冒泡,只有父/祖先组件能通过@事件名监听;但用$root作为事件总线时,就脱离了组件层级的限制,变成全局范围的事件通信。

注意事项

  • 使用全局事件总线时,一定要在组件销毁时移除事件监听,避免内存泄漏。比如在myBcomponent.vue中添加销毁钩子:
    beforeUnmount() {
      this.$root.$off('date-updated');
    }
    
  • 如果是Vue 3项目,官方已经移除了$on、$off这类实例方法,建议用Pinia、Vuex这类状态管理库,或者mitt这类轻量事件库来实现跨组件通信。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:55:17