在 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

}

相关推荐
我命由我123455 分钟前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
key_3_feng20 分钟前
评估与对齐:Agent 自我进化的护栏
前端·数据库·agent
LaughingZhu1 小时前
Product Hunt 热榜 2026-10-30:Empacer、Scape、Floot in ChatGPT
java·前端·数据库·人工智能·chatgpt·notion
Lank_M1 小时前
抠图结果缩放后边缘发脏,该怪的不是插值
前端
jerrywus1 小时前
Skill、MCP、Workflow、Rules、Memory 有什么区别?拿几次真实开发任务讲清楚
前端·agent·claude
补码缩写1 小时前
canvas 与 sharp 缩放透明图:默认预乘,非预乘得拆通道
前端
静默回滚1 小时前
抠图 PNG 缩小再放大,边缘又糊又白是两件事
前端
用户11977079480731 小时前
GitHub 电商开源项目分享:用 sharp 批量出饰品主图,试了裁剪、细节图和色彩配置文件三个坑
前端·node.js
deli0072 小时前
地图定位为什么偏了 500 米?GPS 与火星坐标实测
前端
TK泰妞2 小时前
节日促销前,TikTok 商品视频应该提前准备什么?
前端·人工智能·节日