Angular 12路由守卫中skipLocationChange配置不生效如何解决?
问题根因
Angular 路由导航的配置初始化阶段在 CanActivate 守卫执行前就已经完成,导航实例的 extras 属性在进入守卫阶段后已被冻结,直接修改 getCurrentNavigation().extras 的配置不会被后续导航逻辑识别,因此 skipLocationChange 配置不会生效。
可行解决方案
- 方案一:守卫内手动构造带正确配置的导航返回
直接终止当前默认导航,返回带目标配置的UrlTree实例即可让配置生效,示例代码如下:
import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router, UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; @Injectable() export class TestGuard implements CanActivate { constructor(private router: Router) {} canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { // 直接返回带配置的UrlTree,替代当前默认导航 return this.router.parseUrl(state.url, { queryParamsHandling: 'merge', skipLocationChange: true }); } }
- 方案二:在触发导航的源头传入配置
如果导航触发逻辑可控,无需在守卫内修改配置,直接在调用跳转的位置传入对应参数即可:- 代码触发导航的写法:
this.router.navigate(['/你的目标路由'], { skipLocationChange: true, queryParamsHandling: 'merge' })- 模板
routerLink触发导航的写法:
<a routerLink="/你的目标路由" [skipLocationChange]="true" queryParamsHandling="merge">跳转按钮</a>
注意事项
官方不支持在守卫中直接修改当前导航实例的extras属性,该操作属于未定义行为,不同Angular版本的表现可能存在差异,不建议在生产环境使用该写法。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

