如何通过Angular路由守卫在多路由出口展示统一无权限页面?
解决方案:多层嵌套命名路由下的统一无权限页面处理
核心思路
利用Angular路由的命名出口指定+守卫动态导航,无需在每个路由文件重复配置无权限路由,同时保留上层导航布局,仅在权限缺失的层级出口替换为统一无权限页面。
步骤1:定义统一无权限组件
先实现全局的MissingGrantComponent,用于展示无权限提示内容,可根据传入的权限参数动态调整提示文案。
步骤2:修改GrantsGuard逻辑(关键修复)
之前导航失效的核心原因是未指定目标命名出口,Angular默认会将导航应用到primary主出口,而非你的自定义命名出口(main/sub/last)。调整守卫逻辑如下:
import { Injectable } from '@angular/core'; import { CanActivateChild, ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; import { AuthService } from './path/to/auth.service'; @Injectable({ providedIn: 'root' }) export class GrantsGuard implements CanActivateChild { constructor(private authService: AuthService, private router: Router) {} canActivateChild( childRoute: ActivatedRouteSnapshot ): boolean | UrlTree { // 从路由data中获取当前模块的domain(需在路由配置中预先定义) const domain = childRoute.data['domain']; const requiredPermission = `${domain}_VIEW`; if (this.authService.hasPermission(requiredPermission)) { return true; } // 权限校验失败时,导航到当前命名出口的missing-grant路由 return this.router.createUrlTree(['./missing-grant'], { relativeTo: childRoute, outlet: childRoute.outlet, // 指定要替换的目标命名出口 queryParams: { domain }, // 可选:传递domain给无权限组件 preserveQueryParams: true }); } }
步骤3:统一配置missing-grant路由
无需在每个路由文件重复配置,仅在各命名出口的父布局路由下添加一次无权限路由即可:
// 根路由配置示例 const routes: Routes = [ // 主导航层级(main出口) { path: '', component: MainLayoutComponent, // 包含主导航的布局组件 outlet: 'main', canActivateChild: [GrantsGuard], children: [ // 你的主模块业务路由... { path: 'missing-grant', component: MissingGrantComponent } ] }, // 子导航层级(sub出口) { path: '', component: SubLayoutComponent, // 包含子导航的布局组件 outlet: 'sub', canActivateChild: [GrantsGuard], children: [ // 你的子模块业务路由... { path: 'missing-grant', component: MissingGrantComponent } ] }, // 深层侧边菜单层级(last出口) { path: '', component: LastLayoutComponent, // 包含侧边菜单的布局组件 outlet: 'last', canActivateChild: [GrantsGuard], children: [ // 你的深层业务路由... { path: 'missing-grant', component: MissingGrantComponent } ] } ];
效果验证
- 主权限缺失:
main出口被替换为无权限页面,主导航(MainLayoutComponent)保留 - 子层级权限缺失:
sub出口被替换为无权限页面,主导航+子导航(SubLayoutComponent)保留 - 深层权限缺失:
last出口被替换为无权限页面,主导航+子导航+侧边菜单(LastLayoutComponent)保留
额外优化
- 在
MissingGrantComponent中通过ActivatedRoute接收domain参数,动态生成提示文案:
import { ActivatedRoute } from '@angular/router'; constructor(private route: ActivatedRoute) { const domain = this.route.snapshot.queryParams['domain']; this.tipMessage = `您没有${domain}模块的查看权限`; }
- 若需统一处理所有权限缺失场景,可在守卫中加入日志记录,便于后续排查。
内容的提问来源于stack exchange,提问作者mat.hudak
相关产品推荐
相关产品推荐

