Vue2中子组件$emit发送事件后父组件回调未触发的问题排查
问题核心成因
- 自定义事件监听绑定位置错误
你目前将@book-refresh事件监听器写在了v-for循环的普通<div>DOM节点上。Vue2中通过$emit触发的组件自定义事件,不走原生DOM的冒泡机制,只有直接绑定在子组件对应标签上的监听器,才能被父组件正常捕获。绑定在外层普通DOM节点上的监听器,完全无法接收子组件抛出的自定义事件,这就是回调函数中的console.log始终不输出的根本原因。 - 回调函数语法定义错误
你在refreshbooks函数体内部的this.$set()调用后,悬空写了.bind(this)调用。这个写法既没有指定绑定的目标,也没有把绑定后的方法赋值给任何变量,完全属于无效代码,甚至会造成方法定义的解析异常,即便事件绑定位置正确,方法也无法正常执行。
修正方案
- 调整事件绑定位置:把
@book-refresh从外层循环div节点,移动到<BookCard>子组件标签上 - 修正回调函数的无效写法:移除错误位置的手动
.bind(this)调用——Vue的methods选项内定义的方法,会自动绑定当前组件实例的this指向,无需手动绑定;同时因为你是整体替换书单数组,不需要额外调用$set,直接给this.books赋值即可触发视图响应。
修正后的父组件模板代码
<div v-for="book in books" :key="book.BookID"> <BookCard :book="book" @book-refresh="refreshbooks" /> </div>
修正后的父组件回调函数
async refreshbooks(newbooks) { console.log('in books.vue, starting refreshBooks, newbooks is: ', newbooks) this.books = newbooks }
补充说明:你子组件内的删除逻辑已经验证过可以携带正确数据触发
$emit,只要父组件的事件绑定位置调整到子组件标签上,事件就能正常被监听到,不需要改动子组件的现有删除逻辑。
内容的提问来源于stack exchange,提问作者Athelene Gosnell
相关产品推荐
相关产品推荐

