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
相关产品推荐
相关产品推荐

