在 Vue3 + Vite 项目里,动态路由一般有 3 种常见场景

在 Vue3 + Vite 项目里,动态路由一般有 3 种常见场景,通常用的是 「后端返回菜单 → 前端动态生成路由」 这一套。

✅ 一、先理解什么是动态路由

动态路由 ≠ /user/:id 这种参数路由。

在后台系统里通常指:

👉 运行时动态 addRoute

登录后才加载页面

根据权限加载页面

后端控制菜单

例如:

{ "name": "WeakPlan", "path": "/plan/weak", "component": "plan/weak/index" }

前端收到后动态注册。

✅ 二、目录结构(推荐)

src

├── router

│ ├── index.ts # 路由入口

│ ├── dynamic.ts # 动态路由处理

│ └── modules

├── views

│ ├── plan

│ │ └── weak

│ │ └── index.vue

✅ 三、基础路由(固定路由)

先写不会变的页面:

// router/index.ts

import { createRouter, createWebHistory } from 'vue-router'

export const constantRoutes = [

{

path: '/login',

component: () => import('@/views/login/index.vue')

},

{

path: '/',

component: () => import('@/layout/index.vue'),

redirect: '/dashboard'

}

]

const router = createRouter({

history: createWebHistory(),

routes: constantRoutes

})

export default router

✅ 四、核心:动态加载 view(Vite 写法)

⚠️ Vite 不能用 webpack 的 require。

必须用:

⭐ import.meta.glob(重点)

// router/dynamic.ts

// 自动扫描 views 下所有页面

const modules = import.meta.glob('.../views/**/*.vue')

得到类似:

{

".../views/plan/weak/index.vue": () => import(...)

}

✅ 五、后端路由 → Vue Router 转换

示例后端数据

{

"path": "/plan/weak",

"name": "WeakPlan",

"component": "plan/weak/index"

}

转换函数

import router from './index'

const modules = import.meta.glob('.../views/**/*.vue')

export function loadAsyncRoutes(routes: any[]) {

routes.forEach(route => {

复制代码
const componentPath =
  `../views/${route.component}.vue`

route.component = modules[componentPath]

router.addRoute(route)

})

}

✅ 六、登录后动态注册(真正项目写法)

// login 成功后

const menuRoutes = await getUserMenus()

loadAsyncRoutes(menuRoutes)

✅ 七、刷新页面丢失路由(必须解决)

动态路由最大坑:

👉 F5 刷新后 addRoute 消失

解决方案:

在路由守卫里重新加载

let isLoaded = false

router.beforeEach(async (to, from, next) => {

if (!isLoaded && token存在) {

复制代码
const routes = await getUserMenus()
loadAsyncRoutes(routes)

isLoaded = true

next({ ...to, replace: true })
return

}

next()

})

✅ 八、支持 Layout 嵌套路由(后台必备)

后端返回:

{

"path": "/plan",

"component": "Layout",

"children": [

{

"path": "weak",

"component": "plan/weak/index"

}

]

}

前端处理:

import Layout from '@/layout/index.vue'

if (route.component === 'Layout') {

route.component = Layout

}

相关推荐
OpenTiny社区7 分钟前
GenUI SDK 生成式UI:六大开发特性详解,适配多种业务场景
前端·github·ai编程
大家的林语冰20 分钟前
TS 登顶第一语言;JS 最新 Temporal 时间减屎;Node 爆发反 AI 运动;CSS 将支持图片亮暗切换《前端周刊》
前端·javascript·css
Hilaku27 分钟前
OpenClaw 为什么突然不火了?
前端·javascript·程序员
精益数智工坊36 分钟前
物料管理是什么?物料管理的具体工作有哪些?
大数据·前端·数据库·人工智能·精益工程
岩岩很哇塞!1 小时前
【vue实现模仿探探卡片滑动切换效果】
前端·javascript·vue.js
无我Code2 小时前
全套开源:一款云端服务+本地设备计算的文生图应用
前端·人工智能·后端
用户69371750013842 小时前
实测可用|小米 MiMo 百万亿 Token 免费领,开发者速冲
前端·后端·ai编程
前端小万2 小时前
令人头痛的前端环境
前端·前端工程化
明月_清风2 小时前
Nginx 模块机制深度解析:从核心原理到生产实践
前端·nginx
APIshop3 小时前
1688 跨境寻源通详情接口深度解析:从接入到实战
前端·网络·chrome