背景
在开发 Vue 项目时,动态路由是必要功能,从后端或本地获取到菜单列表的 component 都是是字符串,要转成动态加载方式。因为项目用到了 monorepo,有多个子模块,但有的子模块是直接被引用的,不会单独打包,没有 vite.config.ts 配置,也就没有 @ 别名,转换路由的功能又抽成公共函数,这时模块路径就不好处理,因为动态导入路径默认是相对当前模块的。从别名设置处获得灵感,使用 import.meta.url,import.meta.url 返回当前模块的完整 URL,在调用的地方把 import.meta.url 当作参数传递给转换路由的函数,这样在函数中就可以得到该子模块的相对路径了,相当于传递了相对路径。
示例
调用处
typescript
setAsyncRouter(import.meta.url, 'monitor')
转换函数
typescript
const setAsyncRouter = (path: string, module: string) => {
const menuStore = useMenuStore();
const baseUrl = new URL("./", path).href;
const baseRouter: any[] = [
{
path: `/${module}`,,
name: "layout",
component: "views/layout/index.vue",
meta: {
title: "底层layout",
},
children: [],
},
];
const menus = menuStore.asyncMenus;
const asyncRouter = getMenuList(menus, module););
baseRouter[0].children = asyncRouter;
asyncRouterHandle(baseRouter, baseUrl);
};
typescript
function asyncRouterHandle(asyncRouter: Router[], path: string) {
asyncRouter.forEach((item) => {
if (item.component) {
const component = `${path}${item.component}`;
item.component = () => import(component); // 这里要先定义变量再用
}
if (item.children) {
asyncRouterHandle(item.children, path);
}
});
}
需要传递路径的地方都可以这么用。