在 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

}

相关推荐
冰暮流星1 分钟前
javascript之dom方法访问内容
开发语言·前端·javascript
有意义2 分钟前
滴滴一面复盘:从CSS布局到TS核心思想
前端·面试
竹林8182 分钟前
React + wagmi 实战:从零构建一个能“读”能“写”的 DeFi 前端,我踩了这些坑
前端·javascript
我命由我123453 分钟前
在 React 项目中,配置了 setupProxy.js 文件,无法正常访问 http://localhost:3000
开发语言·前端·javascript·react.js·前端框架·ecmascript·js
俺不会敲代码啊啊啊5 分钟前
封装 ECharts Hook 适配多种图表容器
前端·vue.js·typescript·echarts
J2虾虾9 分钟前
在Vue3中推荐使用的函数定义方法
前端·javascript·vue.js
3秒一个大16 分钟前
Cookie/Session vs JWT 双 Token:登录认证方案的演进与对比
前端·安全·ajax
努力的lpp19 分钟前
【小迪安全41天】WEB攻防-ASP应用&HTTP.SYS&短文件&文件解析&Access注入&数据库泄漏
前端·安全·http
yellowbuff20 分钟前
巧用IntersectionObserver 与 Suspense,实现真正的视口内懒加载(vue3)
前端
A923A20 分钟前
【从零开始学 React | 第一章】React 基础与 JSX 核心语法
前端·react.js·前端框架·jsx