在做这个动态路由的时候踩了很多坑,其中大部分是粗心了
动态菜单主要是导入的方式 import.meta.glob
参考:功能 | Vite 官方中文文档
1、多层路由渲染(用3层路由做demo)
拿到接口的数据是后台直接处理好的结构,但是在addRoute的时候发现其他层没有添加上,这个地方就处理成一级目录先把动态路由添加上再说
const whiteList = ['/login']// 免登录白名单
const modules = import.meta.glob('../views/**/*.vue')
router.beforeEach((to, from, next) => {
document.title = `${to.meta.title}`
const token=Cookies.get('token')
if(token){
if (to.path === '/login') {
next()
}else{
if(store.state.menulist.length==0){
$api.getUserData().then(res =>{
if(res){
if(res.code==0){
let menulist=[];
let newChildren=[];
for(let i=0;i<res.data.menuWithCurrentRoleList.length;i++){
let item=res.data.menuWithCurrentRoleList[i];
let children=[];
if(item.subMenuList){
for(let j=0;j<item.subMenuList.length;j++){
let items=item.subMenuList[j]
items.path=items.router;
let asarr=[];
if(items.subMenuList){
for(let jj=0;jj<items.subMenuList.length;jj++){
let as=items.subMenuList[jj]
let aobjs={
"path":as.href,
"name":as.moduleName,
children:[],
subMenuList:as.subMenuList,
parent:3,
"meta":{
"title":as.name,
},
// component: () => import(`../views${as.href}.vue`),/**这个静态路由只能本地使用**/
component: modules[`../views${as.href}.vue`],
}
asarr.push(aobjs)
newChildren.push(aobjs)
}
}
let aobj={
"path":items.href,
"name":items.moduleName,
children:[],
parent:2,
subMenuList:asarr,
"meta":{
"title":items.name,
},
// component: () => import(`../views${items.href}.vue`),
component: modules[/* @vite-ignore */`../views${items.href}.vue`],
}
children.push(aobj)
newChildren.push(aobj)
}
}
let obj={
"path":item.href,
"name":item.moduleName,
children:[],
parent:1,
subMenuList:children,
"meta":{
"title":item.name,
},
// component: () => import(`../views${item.href}.vue`),
component: modules[`../views${item.href}.vue`],
}
// console.log(obj.component,'====111===',item.href)
menulist.push(obj)
newChildren.push(obj)
}
store.dispatch('setMenulist',newChildren).then(() => {
newChildren.forEach((route) => {
router.addRoute('home',{ ...route });
});
next({ ...to, replace: true });
});
}
}
})
}else{
next()
}
}
}else{
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next()
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
}
}
})
说明:
import.meta.glob('../views/**/*.vue')
一个*表示文件,两个**表示文件夹,.vue是说这个下面的所有.vue文件
我当时遇到的问题有点奇怪,有的路由菜单可以点击,有的不可以,我当时粗心有2点。
1、文件名大小写被我忽略了,没有注意到,所以,一定要注意文件名有没有错
2、使用modules的时候我第三层的前面加了()=>然后在打印component的时候, 打印出来的是变量名
第一个框起来的是路径错误,我没有这个文件
第二个框起来的是正确的,路径正确也可以正常访问
第三个错误的,因为我加了component:()=>modules,实际不需要加,我当时没有注意到这个地方,找了好久的问题
最后:如果有好的多层动态菜单处理方法,大家可以告诉我呀。