引言:
不同的账号有不同的权限, 根据不同权限显示不同
粗略的流程图

首先 在router.js中定义基本路由(登录 404等)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
component: () => import('@/views/AboutView'),
}
]
在当前文件定义前置处理
router.beforeEach((to, from, next) => {
/**
* 大体流程
* 1. 定义路由白名单(登录等...), 放行
* 2. token: 是否登录 未登录 跳转到login
* 3. 根据token向后台获取菜单 权限等 (一般会本地存储 vuex结合localStore使用)
* 4. 根据菜单构建动态路由
* 5. next
*/
// 仅为了演示
console.log(to)
// 向后台获取菜单树
let menuList = getMenu('1');
// 如果动态路由为空 (刷新也会清空 所以我们把动态路由放到vuex中 vuex刷新后也会清空)
const length = store.state.routerList.length;
if (length === 0) {
loadDynamicRouter(menuList)
next({...to, replace: true})
}
next();
})
// 加载路由
function loadDynamicRouter(menuList = []) {
const routers = getRouter(menuList);
// 设置路由
routers.forEach(r => router.addRoute(r))
// 解决刷新后页面404
router.addRoute({'path': '*', component: () => import('@/views/404')})
store.state.routerList = routers;
}
// 向后台获取菜单树
function getMenu(roleId) {
const item = localStorage.getItem("MENU");
if (item !== null) {
return JSON.parse(item)
}
axios.get("http://localhost:48083/screen-gateway/get-menu?roleId=" + roleId).then(res => {
const menuList = res.data.data;
localStorage.setItem("MENU", JSON.stringify(menuList))
return menuList;
})
}
动态路由工具类.js
export function getRouter(menuList = []) {
const routers = []
menuRecursion(menuList, routers)
return routers;
}
// 递归设置路由信息
function menuRecursion(menus = [], routers = []) {
menus.forEach(menu => {
if (menu.pid !== null && menu.pid !== 0) {
const children = menu.children;
children.forEach(child => {
const route = getRealRoute(child);
routers.push(route)
// 递归实现
menuRecursion(child.children, routers)
})
}
})
}
/**
* 获取路由标准
*/
function getRealRoute(item) {
// 路由基本格式
return {
// 路由的路径
path: item.component,
// 路由名
name: item.name,
// 路由所在组件
component: resolve => require([`@/views${item.component}.vue`], resolve),
meta: {
id: item.id,
icon: item.icon
},
// 路由的子路由
children: []
}
}
引入element ui 根据每个人不同的权限 显示不同的菜单
<el-menu
default-active="1"
class="el-menu-vertical-demo"
:router="true">
<template v-for="menu in menus">
<el-submenu index=i v-if="menu.children !=null && menu.children.length>0">
<!-- 有子菜单-->
<template slot="title">
<i class="el-icon-location"></i>
<span>{{ menu.name }}</span>
</template>
<!-- 子菜单 -->
<template v-for="child in menu.children">
<el-menu-item :index="child.component" :path="child.component">
<template>{{ child.name }}</template>
</el-menu-item>
</template>
</el-submenu>
<el-menu-item v-else>
<i class="el-icon-location"></i>
<span>{{ menu.name }}</span>
</el-menu-item>
</template>
</el-menu>
后端代码
list转树的代码 https://blog.csdn.net/weixin_44912855/article/details/122175225
@GetMapping("/get-menu")
public R<List<Perm>> getMenu(@RequestParam(defaultValue = "1") String roleId) {
List<RolePerm> list = rolePermService.list(Wrappers.<RolePerm>lambdaQuery().eq(RolePerm::getRoleId, roleId));
List<Perm> perms = permService.listByIds(list.stream().map(RolePerm::getPermId).collect(Collectors.toList()));
// 转树
ListToTreeHandler<Perm, String> handler = new ListToTreeHandler<>(perms, Perm::getId, Perm::getPid, Perm::setChildren);
return R.success(handler.build());
}