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

Angular 14如何依据路由权限控制隐藏页面跳转按钮?

解决方案

核心思路是复用路由配置中已定义的权限规则,避免在按钮处重复硬编码权限字符串,所有权限判断逻辑统一依赖路由的data.role配置。

1. 封装路由权限检查服务

先写一个全局服务,用来查找目标路由的权限配置,并判断当前用户是否具备访问权限:

import { Injectable } from '@angular/core';
import { Router, Route } from '@angular/router';

@Injectable({ providedIn: 'root' })
export class RoutePermissionService {
  constructor(private router: Router) {}

  // 递归遍历路由配置树,找到匹配目标路径的路由
  private findTargetRoute(targetPath: string, routes: Route[]): Route | null {
    for (const route of routes) {
      // 匹配当前路由的path
      if (route.path === targetPath) {
        return route;
      }
      // 递归查找子路由(处理嵌套路由场景)
      if (route.children?.length) {
        const matchedRoute = this.findTargetRoute(targetPath, route.children);
        if (matchedRoute) return matchedRoute;
      }
    }
    return null;
  }

  // 判断当前用户是否能访问目标路径
  canAccess(targetPath: string): boolean {
    const targetRoute = this.findTargetRoute(targetPath, this.router.config);
    // 如果路由没配置权限,默认允许访问(可根据你的需求调整)
    if (!targetRoute?.data?.role) return true;

    // 替换成你项目中实际获取用户权限的逻辑(从JWT解析)
    const userPermissions = this.getUserPermissions();
    return userPermissions.includes(targetRoute.data.role);
  }

  // 示例:从JWT中解析用户权限,实际项目替换成你的逻辑
  private getUserPermissions(): string[] {
    const authToken = localStorage.getItem('authToken');
    if (!authToken) return [];
    // 实际解析JWT的逻辑:拆分token、解码payload
    // const payload = JSON.parse(atob(authToken.split('.')[1]));
    // return payload.permissions || [];
    return ['user.read']; // 这里用模拟数据,实际替换成真实解析结果
  }
}

2. 在组件中用服务控制按钮显示

在你的导航组件(或任何包含该按钮的组件)中注入服务,然后在模板里用*ngIf控制按钮是否显示:

组件代码

import { Component } from '@angular/core';
import { RoutePermissionService } from './route-permission.service';

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
})
export class NavComponent {
  // 把服务设为public,方便模板直接调用
  constructor(public routePermService: RoutePermissionService) {}
}

模板代码

<button *ngIf="routePermService.canAccess('users')" [routerLink]="['/users']">用户管理</button>

3. 兼容带参数的路由(可选)

如果你的路由是带动态参数的(比如path: 'users/:id'),可以修改findTargetRoute方法,支持匹配动态路由:

private findTargetRoute(targetPath: string, routes: Route[]): Route | null {
  const targetSegments = targetPath.split('/').filter(seg => seg);
  for (const route of routes) {
    const routeSegments = route.path?.split('/').filter(seg => seg) || [];
    // 判断路由片段是否匹配(支持:id这种动态参数)
    const isMatched = routeSegments.every((seg, idx) => 
      seg.startsWith(':') || seg === targetSegments[idx]
    );

    if (isMatched) return route;

    if (route.children?.length) {
      const matchedRoute = this.findTargetRoute(targetPath, route.children);
      if (matchedRoute) return matchedRoute;
    }
  }
  return null;
}

关键提示

  • 所有权限规则都统一维护在路由配置里,后续要修改权限只需要改路由的data.role,不用改组件或模板,减少重复代码。
  • getUserPermissions方法一定要替换成你项目中实际的JWT解析逻辑,确保能正确拿到当前用户的权限列表。
  • 递归查找逻辑会自动处理嵌套路由,不管你的路由层级有多深,都能找到对应的配置。

内容的提问来源于stack exchange,提问作者Ben Robinson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 12:25:23