Vue2/Nuxt2中Buefy对话框触发Axios后emit失效问题求助
Vue2/Nuxt2中Buefy对话框触发后emit失效问题的解决
问题描述
在Vue2/Nuxt2开发功能时,需要实现以下流程:Buefy对话框确认后调用Axios Post请求(后续改为Delete),请求完成后通过emit通知父组件关闭面板并重新加载用户列表。直接通过按钮调用Axios时emit功能正常,但通过对话框触发时emit失效。曾怀疑this指向丢失,尝试保存this未解决;使用await后虽有效果,但重新加载用户列表时仍包含刚删除的用户,推测是emit触发过早。
原始代码
removeUser() { this.$buefy.dialog.confirm({ message: 'Continue on this task?', onConfirm: () => { this.removeUserFunc() } }) }, removeUserFunc() { // console.log(that) const that = this // Build URL const EndPoint = '/remove_user/' + this.id this.$axios.post(EndPoint).then((res) => { // User Remove Message UserRemoved(this.$swal) that.$parent.$emit('completed') // console.log(this.$emit('complete')) // // Emit 'completed' Message console.log(that.$emit('completed')) console.log(that) }).catch((res) => { console.log(res) // Check For Errors GeneralError(this.$swal) }) }
尝试的await版本代码
removeUser() { this.$buefy.dialog.confirm({ message: 'Continue on this task?', onConfirm: async() => { this.removeUserFunc() await this.$emit('completed') } }) },
解决方案
1. 让removeUserFunc返回Promise,确保请求完成后再触发emit
修改removeUserFunc,返回Axios请求的Promise,同时去掉不必要的that保存(箭头函数已绑定上下文),并在请求成功后直接通过组件自身$emit发送事件:
removeUserFunc() { const EndPoint = '/remove_user/' + this.id // 返回请求的Promise,让外部可以等待请求完成 return this.$axios.post(EndPoint).then((res) => { UserRemoved(this.$swal) // 直接使用this.emit,无需操作$parent this.$emit('completed') }).catch((res) => { console.log(res) GeneralError(this.$swal) // 抛出错误,让调用方可以捕获请求失败的情况 throw res }) }
2. 在对话框的onConfirm中正确等待请求完成
修改removeUser方法,使用await等待removeUserFunc执行完毕,确保请求成功后再完成后续流程:
removeUser() { this.$buefy.dialog.confirm({ message: 'Continue on this task?', onConfirm: async () => { // 等待请求完成,确保emit在请求成功后触发 await this.removeUserFunc() } }) }
3. 修正父组件的事件监听方式
不要直接使用$parent.$emit,Vue组件间通信应通过子组件自身$emit,父组件在使用子组件时监听对应的事件:
<!-- 父组件模板中 --> <your-child-component @completed="handleUserRemoved" />
在父组件的handleUserRemoved方法中处理关闭面板和重新加载用户列表的逻辑:
handleUserRemoved() { // 关闭面板逻辑 // 重新加载用户列表逻辑 }
问题根源分析
- 之前使用
that.$parent.$emit是错误的,组件间通信应通过子组件自身触发事件,父组件监听,而非直接操作父组件实例。 - 尝试的await版本无效,是因为
$emit是同步方法,await this.$emit('completed')没有意义,且未等待removeUserFunc中的Axios请求完成就触发了emit,导致父组件提前刷新列表,此时删除请求可能还未完成。
内容的提问来源于stack exchange,提问作者C0ol_Cod3r
相关产品推荐
相关产品推荐

