在 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

}

相关推荐
咩咩啃树皮10 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny10 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹10 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny11 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
小林ixn11 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker12 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜12 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康12 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
一点一木13 小时前
从60首歌到1个网站:输入你的故事,还你一首歌
前端·github
IT_陈寒14 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端