fix(router): 解决页面刷新时NavigationGuard阻止路由跳转的问题

- 修复NavigationGuard在页面刷新时错误地阻止路由导航的问题
- 添加页面刷新检测逻辑,允许刷新场景下的正常导航
- 优化防抖机制,使用时间戳进行更精确的重复点击检测
- 修复"Navigation aborted from '/' to '/system/user'"错误

问题原因:
NavigationGuard的beforeEach守卫与主路由守卫冲突,在页面刷新时
误判正常的路由重定向为重复导航而阻止跳转。

解决方案:
1. 检测页面刷新场景(from.name为空或路径为'/')
2. 使用时间戳替代简单的路径对比进行防抖判断
3. 优化导航状态重置逻辑,保持防抖效果的同时允许正常导航
This commit is contained in:
Leo 2025-07-06 03:21:12 +08:00
parent 92ab0c3159
commit b8d6e5d781

View File

@ -9,6 +9,7 @@ export class NavigationGuard {
private pendingNavigation: string | null = null private pendingNavigation: string | null = null
private navigationTimer: NodeJS.Timeout | null = null private navigationTimer: NodeJS.Timeout | null = null
private readonly NAVIGATION_DEBOUNCE = 100 // 100ms防抖 private readonly NAVIGATION_DEBOUNCE = 100 // 100ms防抖
private lastNavigationTime = 0
constructor(router: Router) { constructor(router: Router) {
this.router = router this.router = router
@ -18,13 +19,34 @@ export class NavigationGuard {
private setupGuards() { private setupGuards() {
// 在路由开始时设置导航状态 // 在路由开始时设置导航状态
this.router.beforeEach((to, from, next) => { this.router.beforeEach((to, from, next) => {
// 如果正在导航中,取消之前的导航 const targetPath = to.fullPath
if (this.isNavigating && this.pendingNavigation === to.fullPath) { const currentTime = Date.now()
// 检查是否是页面刷新或首次加载from.name为null或undefined
const isPageRefresh = !from.name || from.fullPath === '/'
// 如果是页面刷新,直接重置状态并允许导航
if (isPageRefresh) {
this.resetNavigationState()
this.lastNavigationTime = currentTime
next()
return
}
// 检查是否是快速重复点击(时间间隔小于防抖时间且目标路径相同)
const timeSinceLastNavigation = currentTime - this.lastNavigationTime
const isQuickDuplicate = timeSinceLastNavigation < this.NAVIGATION_DEBOUNCE
&& this.pendingNavigation === targetPath
if (isQuickDuplicate) {
console.warn('快速重复导航被阻止:', targetPath)
return next(false) return next(false)
} }
// 更新导航状态
this.isNavigating = true this.isNavigating = true
this.pendingNavigation = to.fullPath this.pendingNavigation = targetPath
this.lastNavigationTime = currentTime
// 清除之前的定时器 // 清除之前的定时器
if (this.navigationTimer) { if (this.navigationTimer) {
@ -59,6 +81,7 @@ export class NavigationGuard {
} }
this.isNavigating = false this.isNavigating = false
this.pendingNavigation = null this.pendingNavigation = null
// 注意:不重置 lastNavigationTime保持防抖效果
} }
/** /**