有人问我二级路由3级路由是如何添加的,我这里大概说一下吧,我们添加动态路由的时候,最好是在路由上添加meta内容,里面写入我们的该路由的父路由的name信息,(一级路由写就可以了),如下图
const routerlist = [
{
path: "/defa",
name: "defa",
component: () => import("@/views/DefaCat.vue"),
meta:"home", //写入父路由的name信息。这里的意思就是把这个路由归置到home路由下边
children: [
{
path: "/defa/fase1",
name: "homelist1",
component: () => import("@/views/UserZi.vue"),
meta:"defa",
children:[
{
path: "/defa/fase1/fase3",
name: "homelist4",
component: () => import("@/views/ComData.vue"),
meta:"homelist1",
}
]
},
],
},
{
path: "/defa/fase2",
name: "homelist2",
component: () => import("@/views/UserZi.vue"),
meta:"home",
},
];
我这里写了一个处理函数,假设后端返回给我们的是一个这个的路由权限数组["/defa","/defa/fase1","/defa/fase1/fase3"] 按照之前的逻辑是,这个数组会存放在vuex当中,我这里就是在路由前置守卫这里获取到vuex的里的路由表,然后在通过我下方的这个处理函数,将动态路由表里如果匹配不上后端返回路由表里的数据的话,会将内容给剔除掉。代码如下:
const filterRoutes = (targetPaths:any, sourceRoutes:any) => {
return sourceRoutes.map((route:any) => {
const filteredChildren = route.children
? filterRoutes(targetPaths, route.children) // 递归处理子路由
: [];
return {
...route,
children: filteredChildren,
};
}).filter((route:any) => route.children.length > 0 || targetPaths.includes(route.path));
};
在调用,循环,依次传入addrouter里即可,处理函数filterrouter第一个接收的参数是后端传入的路由数组,第二个参数是我们的动态路由,我们不仅路由这里需要处理函数,在我们导航栏那里,也需要我们的处理函数将动态路由处理完后在进行递归渲染我们的导航栏
filterRoutes(arrlist,routerlist).map((item: any) => {
router.addRoute(item.meta,item); //这里的第一个参数是我们要添加路由的父路由,这个会把我们的路由归属到第一个参数的路由下面,第一个参数是父路由的name属性
});
第二种解析办法,稍微简单点
const filterRoutes=(router:any,role:any)=>{
return router.filter((item:any)=>{
return role.indexOf(item.path)!=-1;
}).map((item:any)=>{
if(item.children){
item.children=filterRoutes(item.children,role)
}
return item
})
}
也是利用了递归的方法,对一个数字进行数据筛选,这里给大家分段解释下。代码都是死的,主要是思路和想法,以想法来驱动代码。
const filterRoutes=(router:any,role:any)=>{ //1.接收一个路由数据和权限数组
return router.filter((item:any)=>{ //2.这里首先对第一层的数据进行修改 这里使用了filter方法,这个犯法是判断回调函数里的return是否是true如果是true,则保留当前循环到的哪一个数组,如果不是则不保留
return role.indexOf(item.path)!=-1; //3.通过indexof来判断,路由表里的path是否在role里,如果在的话返会一个具体的下标,如果不在则返回-1,这里是当不等于-1时就将筛选的数据添加进去
}).map((item:any)=>{ //4.这里把第一层的路由表筛选完后,这时候就要筛选第二层了
if(item.children){ //5.这里判断是否有子路由
item.children=filterRoutes(item.children,role) //6.这里使用递归,将子路由筛选过的数据给重新赋值给子路由。将子路由的数据表筛传入函数,然后在重新执行筛选子路由,然后在将清洗后子路由的数据给赋值给当前路由的itrm.childer选项
}
return item //6.然后将筛选过的数据继续循环调用
})
}
第三种方案,建议使用这种
这段时间没事做 就在优化了下方案,这套方案适用于很多场景,可以参考这个。
假设后端传入的是一个这样的路由表["/setting","/setting/index"] ,这里是一级路由和二级,一级路由没有内容展示,是直接重定向到二级路由的。然后再看我们的动态路由表对一下,
const router_user: Array<RouteRecordRaw> = [
{
path: "/setting",
name: "setting",
redirect:'/setting/index',
component: () => import("@/views/setting/SetTing.vue"),
children:[
{
path: "/setting/index",
name: "setting123",
component: () => import("@/views/setting/SetTing.vue"),
},
]
},
{
path: "/setting123",
name: "setting12311",
component: () => import("@/views/setting/SetTing.vue"),
},
];
然后我们定义的静态路由分为2个,一个是登录,还有一个是主页面/home,用来承载动态路由的内容,这个页面用来放导航栏等内容,然后中心区域就是我们的路由视图标签。
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "home",
component: () => import("@/views/home/HomeView.vue"),
redirect: JSON.parse(getrouter() as string)[0],
},
{
path: "/login",
name: "login",
component: () => import("@/views/login/LoginView.vue"),
},
];
我们的筛选动态路由的方案还是参考于第二种解析方法,然后,这里我们有个地方注意下,我们的主路由/home他的重定向是来自JSON.parse(getrouter() as string)[0],,这里是我们获取到的后端传的路由表存储到本地解析后数组的第一位内容,这样就能实现,每次重定向都会重定向到存在的路由了。
所有代码:(仅供参考)
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import { gettoken, filterRoutes,getrouter} from "@/method";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "home",
component: () => import("@/views/home/HomeView.vue"),
redirect: JSON.parse(getrouter() as string)[0],
},
{
path: "/login",
name: "login",
component: () => import("@/views/login/LoginView.vue"),
},
];
const router_user: Array<RouteRecordRaw> = [
{
path: "/setting",
name: "setting",
redirect:'/setting/index',
component: () => import("@/views/setting/SetTing.vue"),
children:[
{
path: "/setting/index",
name: "setting123",
component: () => import("@/views/setting/SetTing.vue"),
},
]
},
{
path: "/setting123",
name: "setting12311",
component: () => import("@/views/setting/SetTing.vue"),
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
router.beforeEach(async (to, from, next) => {
if (gettoken()) {
if (to.path == "/login") {
next("/");
} else {
if (to.name == null) {
const f = filterRoutes(router_user,getrouter())
console.log(f)
f.map((item:any)=>{
router.addRoute('home',item)
})
next({...to,replace:true})
} else {
next();
}
}
} else {
if (to.path == "/login") {
next();
} else {
next("/login");
}
}
});
export default router;