vue3+vite 配置动态路由菜单

·  阅读 5363

接口返回数据格式:

image.png

1、路由文件配置router.ts

import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router';
import { App } from 'vue'
import { createRouterGuards } from "./router-guards"

export const indexChildRoutes = [
  {
    path: '/home',
    name: 'Home',
    hidden: false,
    meta: { title: '首页', hidden: false, icon: 'icon-ic_menu_home' },
    component: () => import(/* @vite-ignore */`../views/home/index`)
  }
]
export const routes: RouteRecordRaw[] = [
  {
    path: '/login',
    name: 'Login',
    component: () => import("../views/LoginIndex.vue")
  },
  {
    path: '/',
    name: 'sysjindex',
    component: () => import('../layouts/BasicLayoutIndex.vue'),
    redirect: '/home',
    children: []
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export function setupRouter(app: App) {
  createRouterGuards(router, routes)
  app.use(router)
}


export default router;

// main中使用
// import router, { setupRouter } from './router';
// // 挂载路由
// setupRouter(app)
// 路由准备就绪后挂载APP实例
// router.isReady().then(() => app.mount('#app'))
复制代码

2、./router-guards 设置动态路由

import { Router } from "vue-router"
import store from "../store"

const whiteList = ['/login']
// const store = useStore()

export function createRouterGuards(router: Router, routes: any) {
    router.beforeEach((to, form, next) => {
        let token = localStorage.getItem("token")
        if (token) {
            // console.log(store.state.user.routes.length)
            if (!store.state.user.routes.length) {
                // 拉取useinfo信息
                store.dispatch('GetInfo')
                store.dispatch("GenerateRoutes").then((res) => {
                    const layout = routes.find((item: any) => item.name == 'sysjindex')!
                    layout.children = [...res]
                    router.addRoute(layout)
                    // res.map((item: any) => router.addRoute("sysjindex", item))
                    next({ ...to, replace: true })
                })
            } else {
                next()
            }
        } else {
            // 没有token
            if (whiteList.indexOf(to.path) !== -1) {
                // 在免登录白名单,直接进入
                next()
            } else {
                next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
            }
        }
    })
}
复制代码

2.1、store获取处理getRoutes

// actions
const actions = {
    // 生成路由
    GenerateRoutes({ commit }: ActionContext<any, any>) {
        return new Promise(resolve => {

            // 向后端请求路由数据
            getRouters().then(res => {
                let accessedRoutes = filterAsnycRouter(res.data);
                accessedRoutes = indexChildRoutes.concat(accessedRoutes)
                // accessedRoutes.push({ path: "*", redirect: "/404", hidden: true });

                commit("SET_ROUTES", accessedRoutes);
                // console.log(accessedRoutes)
                resolve(accessedRoutes);
            });
        });
    },
   ...
}
// mutations
const mutations = {
    SET_ROUTES: (state: State, routes: Array<any>) => {
        state.routes = routes;
    },
复制代码

中filterAsnycRouter,在main.ts文件平级目录下新建importRoutercom.ts文件,为了处理。Glob 模式会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)。

2.2、importRoutercom.ts

import 'vite/dynamic-import-polyfill';

export function filterAsnycRouter(asyncRouterMap: any) {
    return asyncRouterMap.filter((route: any) => {
        if (route.component == 'Layout') {
            route.component = () => import('./layouts/BlankIndex.vue')
        } else {
            route.path = `${route.path}`
            route.component = resolveComponent(route.component);
        }
        if (route.children != null && route.children && route.children.length) {
            route.children = filterAsnycRouter(route.children);
        }
        return true;
    })
}

const pages = import.meta.globEager('./views/**/*.vue');
// 以 `./` 开头)或绝对路径(以 `/` 开头

const resolveComponent = (name: any) => {
    const importPage = pages[`./views/${name}.vue`];

    if (!importPage) {
        throw new Error(`Unknown page ${name}. Is it located under Pages with a .vue extension?`);
    }

    // return importPage().then(module => module.default);
    return importPage.default
}
复制代码

处理在build下,unknown variable dynamic import:报错

参照代码:owenconti.com/posts/repla…

image.png

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改