Vue3 setup()内监听器触发$emit失效,父组件如何接收对应事件?
问题原因
你代码失效的核心原因有两个:
- Vue3的
setup()执行阶段组件实例还未完全创建,不存在this指向的组件实例,无法使用this.$emit写法触发事件 - 你给
hello.on传入的是普通函数回调,该函数内的this会指向hello对象,而非你预期的组件实例
解决方法
首先从setup的第二个上下文参数中解构出emit方法,同时将普通函数回调替换为箭头函数,避免this指向问题,修正后代码如下:
setup(props, { emit }) { const showLogout = ref(false) hello.on('auth.login', (auth) => { emit("auth", auth); }) return { showLogout, hello } }
额外注意:必须在组件卸载时移除该事件监听器,避免内存泄漏,完善版代码如下:
import { ref, onUnmounted } from 'vue' setup(props, { emit }) { const showLogout = ref(false) // 将回调存为独立变量,方便后续移除监听 const handleAuthLogin = (auth) => { emit("auth", auth); } hello.on('auth.login', handleAuthLogin) // 组件卸载时移除监听 onUnmounted(() => { hello.off('auth.login', handleAuthLogin) }) return { showLogout, hello } }
其他可注册监听器的位置
- 如果你使用选项式API,可以放在
created生命周期钩子中注册,对应在beforeUnmount钩子中销毁 - 组合式API场景下也可以放在
onMounted钩子中注册,该阶段所有DOM和第三方实例都已完成初始化,能避免hello对象未初始化就绑定监听的异常情况
内容的提问来源于stack exchange,提问作者Mart123
相关产品推荐
相关产品推荐

