vue-router使用addRoute动态添加主界面的子路由
1、需求描述
从别处导出的可用前端文件,存放在系统@/views/下,不配置静态路由,当访问改菜单时,根据当前菜单的path动态向主界面(路由path: '/', name:'homePage')中添加子路由,使其页面可正常访问
注:当前菜单的path,为当前菜单文件存放的路径,如:菜单path为dynamicTest/dynamicTestList的存放位置为@/views/dynamicTest/dynamicTestList.vue
2、解决思路
使用路由beforeEach全局守卫,若当前菜单不在静态路由中,则动态向主界面添加当前菜单的子路由
3、解决过程
1)遍历所有页面文件
注:vue2+vite2+ts项目使用import.meta.globEager方法遍历文件,vue2+webpack+ts项目使用require.context方法遍历文件
2)添加router.beforeEach全局路由守卫
3)判断to.path是否已配置过静态路由,是则执行next(),否则判断to.path对用文件是否存在@/views/文件夹下,是则执行4),否则执行next()
4)定义临时路由变量({name: to.path,path: to.path,component: () => import(文件路径)},并使用router.addRoute方法添加主界面/的子路由
5)vue2+vite2+ts项目具体代码如下:
import { Route, NavigationGuardNext, Location } from 'vue-router';
import router from './router/router'; // 遍历views文件夹下所有的文件 const requireComponent1: any = import.meta.globEager('./views/*.vue'); const requireComponent2: any = import.meta.globEager('./views/**/*.vue'); const requireComponent = {...requireComponent1, ...requireComponent2}; let toPathObj: any = {};
// 全局路由守卫 router.beforeEach(async (to: Route, from: Route, next: NavigationGuardNext) => {
const allRoutes: any = router.getRoutes();
// 判断是否已添加静态路由 const incCurRoute: any = allRoutes.findIndex((it: any) => it.path === to.path) > -1; if(incCurRoute) { next(); return; } // 判断是否已添加动态路由 if(!toPathObj.hasOwnProperty(to.path)) {
// 判断@/views文件夹下是否存在该路由文件 const isIncKey: any = Object.keys(requireComponent).find((key: any) => key.indexOf(to.path) > -1); if(isIncKey) { toPathObj[to.path] = isIncKey; const curRoute: any = { name: to.path, path: to.path, meta: {}, component: () => import(isIncKey), };
// 向name为'homePage'的路由中添加子路由 router.addRoute('homePage', curRoute); next({ ...(to as Location), replace: true }); return; } } next(); }); router.afterEach(() => {});