You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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)保留

额外优化

  1. 在MissingGrantComponent中通过ActivatedRoute接收domain参数,动态生成提示文案:
import { ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {
  const domain = this.route.snapshot.queryParams['domain'];
  this.tipMessage = `您没有${domain}模块的查看权限`;
}
  1. 若需统一处理所有权限缺失场景,可在守卫中加入日志记录,便于后续排查。

内容的提问来源于stack exchange,提问作者mat.hudak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 12:37:17