背景
当基于若依框架进行前端开发时,可能会遇到需要将原有前端拆分为多个独立框架的场景。例如,为了将业务管理后台与对外展示的门户系统在主题配色和风格上完全隔离,就需要拆分为两个独立的前端项目。
拆分后,一个核心问题是如何实现动态菜单。我们希望不同身份的用户登录不同前端时,看到的菜单也不同。这两个前端项目通常对应同一个后端服务,后端返回的菜单数据结构是一致的。如果不想为此修改后端接口逻辑,那么解决方案就需要从前端着手。
思路分析:从前端路由配置入手
查看 router/index.js 文件,在动态路由配置的顶部,通常会看到这样的注释说明:

其中,roles: [‘admin‘, ‘common‘] 和 permissions: [‘a:a:a‘, ‘b:b:b‘] 这两个属性为我们提供了思路。它们分别表示:访问该路由所需的角色权限和菜单权限。这意味着,我们可以利用这些配置,结合前端对用户权限的判断,来控制菜单的显示与隐藏。
因此,解决方案是:在前端预先定义好所有可能的路由配置,然后根据当前用户的角色或权限进行过滤。这样做的优点是无需后端配合修改,缺点是菜单结构固定,如需变更则需要重新打包发布前端。
实现步骤
1. 配置前端路由
在 router/index.js 文件的动态路由部分(注意不是公共路由 constantRoutes),按照格式添加你需要的路由。例如,添加一个只有 common 角色才能访问的测试页面路由:
{
path: ‘/test‘,
component: () => import(‘@/views/powerstation/dashboard‘),
name: ‘test‘,
roles: [‘common‘], // 关键配置:指定可访问的角色
meta: { title: ‘测试‘, icon: ‘dashboard‘ },
}
2. 修改权限生成逻辑
接下来,需要修改权限状态管理。打开 store/modules/permission.js 文件,找到 GenerateRoutes 方法。由于我们不再依赖后端返回动态路由,因此需要注释掉原有的请求逻辑,改为直接使用前端配置的路由并进行过滤。
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 注释掉原有的后端请求逻辑
// getRouters().then(res => {
// const sdata = JSON.parse(JSON.stringify(res.data))
// ...
// })
// 核心改动:直接过滤前端配置的动态路由
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
let tempRoutes = constantRoutes.concat(asyncRoutes)
// 将过滤后的动态路由添加到Vue Router实例
router.addRoutes(asyncRoutes)
// 提交到Vuex store,用于生成侧边栏菜单等
commit(‘SET_ROUTES‘, tempRoutes)
commit(‘SET_SIDEBAR_ROUTERS‘, tempRoutes)
commit(‘SET_DEFAULT_ROUTES‘, tempRoutes)
commit(‘SET_TOPBAR_ROUTERS‘, tempRoutes)
resolve(tempRoutes)
})
}
3. 实现路由过滤逻辑
上述代码中的 filterDynamicRoutes 函数是实现动态菜单的核心。它遍历前端配置的所有动态路由,根据当前用户的权限进行过滤。逻辑如下:
- 如果路由配置了
permissions(权限标识),则检查用户是否拥有其中任意一个权限。
- 如果路由配置了
roles(角色),则检查用户是否拥有其中任意一个角色。
- 超级管理员(admin) 默认拥有所有菜单权限。
// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
const res = []
routes.forEach(route => {
if (route.permissions) {
// 使用权限判断函数
if (auth.hasPermiOr(route.permissions)) {
res.push(route)
}
} else if (route.roles) {
// 使用角色判断函数
if (auth.hasRoleOr(route.roles)) {
res.push(route)
}
}
})
return res
}
4. 后端用户鉴权
至此,前端菜单的动态展示已经完成。但为了系统安全,对应的页面接口在后端仍需进行严格的权限校验,确保用户无法越权访问数据。
完成以上步骤后,刷新页面并用不同角色的用户登录,即可看到根据 roles 或 permissions 配置过滤后的个性化菜单。