接口获取路由结构
安装依赖
npm i vue-router
有时候我们需要从接口获取路由树结构,使用addRouter
动态生成路由配置。
我们先创建一个静态文件,模拟接口返回的路由树结构。
新建文件 src/router/config.ts
// src/router/config.ts
const routerList = [
{
pageCode: 'home',
pageName: '首页',
pageType: 'page',
},
{
pageCode: 'menu',
pageName: '菜单',
pageType: 'menu',
children: [
{
pageCode: 'page1',
pageName: '页面1',
pageType: 'page',
},
{
pageCode: 'page2',
pageName: '页面2',
pageType: 'page',
},
],
},
];
// 模拟接口获取路由树结构
export const getRouterList = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(routerList);
}, 300);
});
};
新建 src/router/components.ts
// src/router/components.ts
import home from '@/views/home.vue';
import page1 from '@/views/menu/page-1.vue';
import page2 from '@/views/menu/page-2.vue';
export default {
home,
page1,
page2,
};
新建文件 src/router/index.ts
// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import components from './components';
const addRouter = (data: any[], result: RouteRecordRaw[]) => {
data.forEach((item) => {
const option: RouteRecordRaw = {
path: item.pageCode.toLowerCase(),
name: item.pageCode,
component: null as any,
redirect: null as any,
};
const component = components[item.pageCode as 'home'];
if (component) {
option.component = component;
}
if (item.pageType === 'menu') {
option.redirect = {
name: item.children[0].pageCode,
};
}
result.push(option);
if (item.children && item.children.length) {
option.children = [];
addRouter(item.children, option.children);
}
});
};
export const initRouter = (data: any[]) => {
const pages = [] as RouteRecordRaw[];
addRouter(data, pages);
const router = createRouter({
history: createWebHistory(''),
routes: [
{
path: '/',
name: 'layout',
redirect: { name: data[0].pageCode },
component: () => import('@/views/layout.vue'),
children: pages,
},
],
});
return router;
};
修改src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import '@/style/index.scss';
import { getRouterList } from '@/router/config';
import { initRouter } from '@/router/index';
(async () => {
const routerList = await getRouterList();
const router = initRouter(routerList as any[]);
const app = createApp(App);
app.use(router);
app.mount('#app');
})();
修改 src/App.vue
至此,通过接口动态生成路由的简单demo已经配置完成,其他页面文件的代码,这里就不展示了。
问题记录
1,项目不是部署在 nginx
的根目录。
解决方案:
创建环境变量:在根目录新增
.env.development
和.env.production
两个文件,设置环境变量,定义nginx
部署路径VITE_APP_PATHNAME = "/nginx_path/" VITE_APP_OUT_DIR="nginx_path"
修改
src/router/index.ts
const router = createRouter({ history: createWebHistory(import.meta.env.VITE_APP_PATH), routes, });
修改
vite.config.ts
// vite.config.ts import { defineConfig, loadEnv } from 'vite'; // https://vitejs.dev/config/ export default (mode) => { const env = loadEnv(mode, process.cwd()); return defineConfig({ // ...other codes base: env.VITE_APP_PATHNAME, build: { outDir: resolve(env.VITE_APP_OUT_DIR), }, }); };