From b8d6e5d7819e32e2e22ae8d0de62ff646526602f Mon Sep 17 00:00:00 2001 From: Leo <98382335+gaoziman@users.noreply.github.com> Date: Sun, 6 Jul 2025 03:21:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(router):=20=E8=A7=A3=E5=86=B3=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=88=B7=E6=96=B0=E6=97=B6NavigationGuard=E9=98=BB?= =?UTF-8?q?=E6=AD=A2=E8=B7=AF=E7=94=B1=E8=B7=B3=E8=BD=AC=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复NavigationGuard在页面刷新时错误地阻止路由导航的问题 - 添加页面刷新检测逻辑,允许刷新场景下的正常导航 - 优化防抖机制,使用时间戳进行更精确的重复点击检测 - 修复"Navigation aborted from '/' to '/system/user'"错误 问题原因: NavigationGuard的beforeEach守卫与主路由守卫冲突,在页面刷新时 误判正常的路由重定向为重复导航而阻止跳转。 解决方案: 1. 检测页面刷新场景(from.name为空或路径为'/') 2. 使用时间戳替代简单的路径对比进行防抖判断 3. 优化导航状态重置逻辑,保持防抖效果的同时允许正常导航 --- src/utils/navigation-guard.ts | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/utils/navigation-guard.ts b/src/utils/navigation-guard.ts index acdda41..e5978c4 100644 --- a/src/utils/navigation-guard.ts +++ b/src/utils/navigation-guard.ts @@ -9,6 +9,7 @@ export class NavigationGuard { private pendingNavigation: string | null = null private navigationTimer: NodeJS.Timeout | null = null private readonly NAVIGATION_DEBOUNCE = 100 // 100ms防抖 + private lastNavigationTime = 0 constructor(router: Router) { this.router = router @@ -18,13 +19,34 @@ export class NavigationGuard { private setupGuards() { // 在路由开始时设置导航状态 this.router.beforeEach((to, from, next) => { - // 如果正在导航中,取消之前的导航 - if (this.isNavigating && this.pendingNavigation === to.fullPath) { + const targetPath = 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) } + // 更新导航状态 this.isNavigating = true - this.pendingNavigation = to.fullPath + this.pendingNavigation = targetPath + this.lastNavigationTime = currentTime // 清除之前的定时器 if (this.navigationTimer) { @@ -59,6 +81,7 @@ export class NavigationGuard { } this.isNavigating = false this.pendingNavigation = null + // 注意:不重置 lastNavigationTime,保持防抖效果 } /**