Vue3 动态路由
我们开发后台管理系统过程中,会由不同的人操作系统,如admin(一般管理员)、superAdmin(超管),及各种运营、财务人员。为了区别这些人员权限,可能会给不同的人分配不一样的角色来展示不同的菜单,这就必须要通过动态路由来实现。下面就来介绍 vue 实现动态路由,需要的朋友可参考一下~
1、登录获取路由 json 数据
login 页面登录,接口返回路由链表(json 数据,父子嵌套形式的),使用 vuex 的异步方法(action)将接口返回的菜单 json 数据(res.data.menuList)存储起来,之后,进行 router 页面跳转(方便大家查看,我这里做了单一层级的菜单+二级菜单)
ts
<script setup lang='ts'>
import { Login } from '@/api/user'
const submit = ()=> {
Login({
username:'米白小站',
password:'mibaixiaozhan'
}).then(res => {
// //接口返回的数据格式,大概是这个样子
// menuList: [
// {//这是一个页面(不含子级)
// "title": "菜单管理",
// "path": "/role",
// "file":"/role.vue"
// },
// {//这是一个模块
// name: "商品管理",
// path: "/goods",
// children: [
// {//这是模块下面的页面
// name: "商品管理模块A页面",
// path: "goods_a",
// route: "/goods/goods_a.vue"
// },
// ...
// ]
// }
// ]
store.dispatch('ACTION_SET_MENUS',res.data.menuList)
router.push('/goods_a')
})
}
</script>
2、添加至 router
在路由文件(router/index.ts)内,将接口返回的 menuList 添加至 router 后,调用 next()方法进行跳转即可
在处理路由 beforeEach 函数的时候,切记,第一步先判断当前页是否为 login 页面
我这里的判断为:
1、 判断当前页是否为 login
2、 是否存在 token
3、 是否加载过路由链表
在确认没有加载过路由链表的时候,调用routerDadaFunc处理路由 json 方法,重置加载状态后,进行页面跳转
ts
const getToken = true; //是否存在token
var isF = false; //判断动态路由是否已经被获取到了
router.beforeEach(async (to, from) => {
if (to.path == "/login") {
return true;
}
if (!getToken) {
return { path: "/login" };
} else {
if (isF) {
return true;
} else {
let add = store.state.resRoute || "";
routerDadaFunc(add);
isF = true;
return { ...to, replace: true };
}
}
});
3、递归处理路由链表
方法说明:此方式使用的是动态拼接静态路由中的 import 加载,然后递归调用,addRoute 添加路由。这种方式简化了使用 name 匹配,接口数据 for 循环套着静态路由 for 循环判断匹配。按照此逻辑搭建好之后,前端只需要新建对应目录的模块/页面组件.vue,完全不用处理路由相关代码,接口返回了一个模块 A,前端对应目录有 A 模块.vue 文件就可以(页尾留有 demo 源码获取方式)
ts
const routerData = (result: any) => {
let currenRoutes = router.options.routes as any;
if (result) {
result.forEach((item: any) => {
// has用于判断当前路由中是否已经具有,避免重复
var has = currenRoutes.some((it) => it.path == item.path);
if (!has) {
currenRoutes.push({
path: `${item.path}`,
name: item.title,
meta: {
title: item.title,
},
component: () => import(`../pages${item.file}`),
});
router.addRoute("home", {
path: `${item.path}`,
name: item.title,
meta: {
title: item.title,
},
component: () => import(`../pages${item.file}`),
});
}
if (item.children && item.children.length) {
routerData(item.children);
}
});
}
};
点击登录之后,页面就是这个样子的了
扫码联系我,获取demo源码
