Vue3 + Vite 实现动态路由

动态路由主要通过router.addRoute()函数实现。

1.路由格式

{
      name: "user",
      path: "/system/user",
      meta: {
        title: "用户管理",
    },
       component: () => import("@/views/User.vue"),
}

2.完整代码

import Home from "@/components/Home.vue";
import { createRouter, createWebHashHistory } from "vue-router";

//Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const modules = import.meta.glob("../views/**.vue")

// 基础路由
const routes = [
  {
    name: "home",
    path: "/",
    meta: {
      title: "首页",
    },
    component: Home,
    redirect: "/welcome",
    children: [
      {
        name: "welcome",
        path: "welcome",
        meta: {
          title: "欢迎页",
        },
        component: () => import("@/views/Welcom.vue"),
      },
      {
        name: "404",
        path: "/404",
        meta: {
          title: "页面不存在",
        },
        component: () => import("@/views/404.vue"),
      },
    ],
  },
  {
    name: "login",
    path: "/login",
    meta: {
      title: "登录",
    },
    component: () => import("@/views/Login.vue"),
  },
];


// 创建路由对象
const router = createRouter({ history: createWebHashHistory(),routes});

async function loadAsyncRoutes() {
  // 判断有没有token
  const userInfo = storage.getItem("userInfo") || {}
  if (userInfo.token) {
    // 从后台获取权限菜单
    const { menuList:routers } = await api.getPermissionList();
    // 如果格式不一致需要 生成路由需要的格式
    {...}
    // 添加到路由表
    routers.map(route => {
       // 动态加载路由
      route.component =  modules[`../views/${route.component}.vue`];
      router.addRoute('home', route);
    })
  }
}


// 路由拦截
router.beforeEach(async (to, from, next) => {
  await loadAsyncRoutes();
   // 判断要跳转地址是否存在路由表里
  const chasPerimissonrouter.getRoutes().filter(router => router.path === to.path).length > 0;
  if (chasPerimissonrouter) {
    document.title = to.meta.title;
    next();
  } else {
    next("/404");
    document.title = "页面不存在";
  }
});

export default router;

3.使用 import引入打包 报错解决

原因:ES6 的动态 import 不支持动态参数,可以使用 Vite 提供的 glob 功能,Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块,需要使用这个方式。

//vite的引入方式
const modules = import.meta.glob("../views/**/**.vue")
 
//"home"加到home的children中
router.addRoute("home", {
          path: `${itemRouter.path}`,
          name: itemRouter.name,
          meta: {
            title: itemRouter.name,
          },
          component: modules[`../views/${itemRouter.component}`],
})
ES6 Vue3 Vue Vite 动态路由 路由拦截 import
Theme Jasmine by Kent Liao