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
相关产品推荐
相关产品推荐

