Vue Router场景下未在其他路由却触发其API请求的原因
问题原因
你遇到的问题是因为DataTable组件在路由切换被销毁时,没有移除eventBus上的'reloadData'事件监听。即便组件已经卸载,它的监听回调仍然保留在eventBus的事件列表中,所以每次触发'reloadData'事件时,所有曾经挂载过的DataTable实例都会执行getRecords(),导致多次API请求。
解决方案
在DataTable组件的生命周期钩子中,组件销毁前移除对应的事件监听。注意必须保存监听的回调函数引用,不能直接使用匿名函数(因为$off需要匹配同一个函数引用才能移除)。
Vue 2 实现
修改DataTable.vue的代码:
<template> <!-- 你的表格结构 --> </template> <script> export default { data() { return { // 保存回调引用 reloadCallback: null } }, mounted() { this.reloadCallback = () => { this.getRecords() } // 绑定事件监听 this.$bus.$on('reloadData', this.reloadCallback) }, destroyed() { // 组件销毁时移除监听 this.$bus.$off('reloadData', this.reloadCallback) }, methods: { getRecords() { // 你的API请求逻辑 console.log('获取数据') } } } </script>
Vue 3 实现(若使用自定义eventBus)
如果是Vue3项目,通常推荐用mitt库实现事件总线,解绑逻辑类似:
<template> <!-- 你的表格结构 --> </template> <script setup> import { onMounted, onBeforeUnmount } from 'vue' import mitt from 'mitt' // 假设全局事件总线挂载在window上 const bus = window.$bus || mitt() const reloadCallback = () => { getRecords() } onMounted(() => { bus.on('reloadData', reloadCallback) }) onBeforeUnmount(() => { bus.off('reloadData', reloadCallback) }) function getRecords() { // 你的API请求逻辑 console.log('获取数据') } </script>
额外建议
如果你的场景只需要当前活跃路由的DataTable刷新,也可以考虑:
- 用路由守卫结合组件内部状态,在路由激活时主动调用
getRecords() - 改用Pinia/Vuex管理表格数据,通过状态变更触发组件刷新,避免使用全局事件总线带来的这类问题
内容的提问来源于stack exchange,提问作者DarkFenix
相关产品推荐
相关产品推荐

