1

接口获取路由结构

安装依赖

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

<template>
    <ElConfigProvider :locale="zhCn">
        <router-view></router-view>
    </ElConfigProvider>
</template>
<script setup lang="ts">
import { zhCn } from 'element-plus/es/locale/index.mjs';
</script>

至此,通过接口动态生成路由的简单demo已经配置完成,其他页面文件的代码,这里就不展示了。

问题记录

1,项目不是部署在 nginx的根目录。
解决方案:

  1. 创建环境变量:在根目录新增 .env.development.env.production 两个文件,设置环境变量,定义 nginx 部署路径

    VITE_APP_PATHNAME = "/nginx_path/"
    VITE_APP_OUT_DIR="nginx_path"
  2. 修改 src/router/index.ts

    const router = createRouter({
     history: createWebHistory(import.meta.env.VITE_APP_PATH),
     routes,
    });
  3. 修改 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),
         },
     });
    };

似曾相识
169 声望8 粉丝