2021,疫情本要缓解又变异的上半年,在五一快要到来之时,我已经苦逼了一月的996。前两天vue+iview的后台管理系统要改造成动态菜单,后台接口返回菜单,处理并生成路由。于是乎开始搞起来,(心态:第一次自己搞这个需求还是很崩溃的)~
当当当 当
部分相关目录
开始上代码:
/**
* 静态路由 容器
*/
const defaultRouter = [
{
path: "/Home",
component: Home
}
];
const router = new VueRouter({
routes:defaultRouter
});
// OnRoute变量避免陷入死循环
let OnRoute = true;
router.beforeEach((to,from,next)=>{
if(OnRoute){
// 首次进入Home存储token
if(to.path=="/Home"&&to.query){
// 处理
createNewRouter(to.query.menuItemId);
next()
}else{
// 刷新,跳因为Home是页面容器。
createNewRouter();
next({
path: '/Home?Refresh=1',
})
// next({...to, replace: true})//如果容器是"App",这个必不可少的,确保你的动态路由创建成功再去执行其它代码
}
}else{
// 菜单切换
if(to.path!=="/Home"){
// 记录菜单
sessionStorage.setItem("pathUrl", to.path);
}
next()
}
})
function createNewRouter(val){
// 在这里做你登陆之后所做的创建动态路由的事情,因为router.addRoutes刷新会丢失,
if(val){
// 首次获取菜单
store.dispatch("GetMenu",{menuId:val}).then(res => {
})
}else{
// 刷新后获取菜单
let id = sessionStorage.getItem("MenuID");
store.dispatch("GetMenu",{menuId:id}).then(res => {
})
}
OnRoute = false; // 必须在creatNewRouter() 执行
};
export default router;
在store中调接口获取菜单后用getAsyncRoutes()处理结构。(具体代码就不贴了…)
function getAsyncRoutes(routes) {
const res = []
routes.forEach(route => { // 所有菜单都是二级结构,一级没有页面功能,所以只要添加二级菜单的路由
if (route.children.length !== 0) {
const children = []
route.children.forEach(menu => { // 二级菜单需匹配页面
children.push({
path: menu.menuItemUrl,
name: menu.menuItemNm,
key: menu.key,
// 此处也可使用require
component: () => import("@/views"+menu.menuItemUrl),
meta: { processForm: menu.processForm,validInd:menu.validInd } // 菜单权限
})
})
res.push({
path: '/Home',
name: route.menuItemNm,
component: Home,
children: children
})
}
})
// 将菜单提取出来的路由加到路由表
router.addRoutes(res);
router.options.routes = res;
store.commit("SET_MENUS", res);
// 暂存菜单到本地
sessionStorage.setItem("MenuArr",JSON.stringify(res))
return res
}
export default getAsyncRoutes
最后一步在 Home中Menu做简单处理展示即可,O(∩_∩)O哈哈~,来自分享的快乐。五一快乐