权限路由动态注册使用说明和完整示例
一、 核心原理与使用说明路由分层将路由分为constantRoutes无需权限的静态路由如登录、404和asyncRoutes需要权限的动态路由。组件懒加载Vite 不支持require.context必须使用import.meta.glob批量导入views下的组件。动态挂载使用 Vue Router 4 提供的router.addRoute()将过滤后的路由添加到指定的父级布局Layout下。刷新防丢失页面刷新会导致内存中的动态路由丢失。必须在router.beforeEach中判断如果已登录但路由未生成则重新拉取权限并生成路由最后使用next({ ...to, replace: true })重新触发导航。菜单联动侧边栏菜单应直接读取生成后的路由表结合meta字段保证路由与菜单的绝对一致。二、 完整实战示例1. 定义路由表 (src/router/routes.ts)importtype{RouteRecordRaw}fromvue-router// 1. 静态路由无需权限exportconstconstantRoutes:RouteRecordRaw[][{path:/login,name:Login,component:()import(/views/login/index.vue),meta:{hidden:true}},{path:/404,name:NotFound,component:()import(/views/error/404.vue),meta:{hidden:true}}]// 2. 动态路由需要权限// 注意必须配置 name否则重置路由时可能会出问题exportconstasyncRoutes:RouteRecordRaw[][{path:/system,name:System,component:()import(/layouts/DefaultLayout.vue),redirect:/system/user,meta:{title:系统管理,icon:setting,roles:[admin]},children:[{path:user,name:SystemUser,component:()import(/views/system/user/index.vue),meta:{title:用户管理,roles:[admin]}},{path:role,name:SystemRole,component:()import(/views/system/role/index.vue),meta:{title:角色管理,roles:[admin]}}]},// ️ 404 兜底路由必须放在最后动态添加{path:/:pathMatch(.*)*,redirect:/404,meta:{hidden:true}}]2. 封装权限 Store (src/stores/modules/permission.ts)import{ref}fromvueimport{defineStore}frompiniaimporttype{RouteRecordRaw}fromvue-routerimport{asyncRoutes,constantRoutes}from/router/routes// 使用 Vite 的 import.meta.glob 预加载所有视图组件constmodulesimport.meta.glob(/views/**/*.vue)exportconstusePermissionStoredefineStore(permission,(){constroutesrefRouteRecordRaw[]([])constisRoutesGeneratedref(false)// 核心根据角色过滤路由functionfilterAsyncRoutes(routeList:RouteRecordRaw[],roles:string[]):RouteRecordRaw[]{constres:RouteRecordRaw[][]routeList.forEach(route{consttmp{...route}if(hasPermission(tmp,roles)){if(tmp.children){tmp.childrenfilterAsyncRoutes(tmp.children,roles)}// 将字符串组件路径转换为真实的懒加载组件if(typeoftmp.componentstring){tmp.componentmodules[/src/views/${tmp.component}.vue]}res.push(tmp)}})returnres}functionhasPermission(route:RouteRecordRaw,roles:string[]):boolean{if(route.meta?.roles){returnroles.some(role(route.meta!.rolesasstring[]).includes(role))}returntrue}// 生成动态路由并缓存functiongenerateRoutes(roles:string[]):RouteRecordRaw[]{letaccessedRoutes:RouteRecordRaw[]if(roles.includes(admin)){accessedRoutesasyncRoutes||[]}else{accessedRoutesfilterAsyncRoutes(asyncRoutes,roles)}routes.valueconstantRoutes.concat(accessedRoutes)isRoutesGenerated.valuetruereturnaccessedRoutes}// 退出登录时重置functionresetRoutes(){routes.value[]isRoutesGenerated.valuefalse}return{routes,isRoutesGenerated,generateRoutes,resetRoutes}})3. 配置路由守卫 (src/router/index.ts)import{createRouter,createWebHistory}fromvue-routerimport{constantRoutes}from./routesimport{useUserStore}from/stores/modules/userimport{usePermissionStore}from/stores/modules/permissionconstroutercreateRouter({history:createWebHistory(import.meta.env.BASE_URL),routes:constantRoutes,scrollBehavior:()({top:0})})constwhiteList[/login]router.beforeEach(async(to,from,next){constuserStoreuseUserStore()constpermissionStoreusePermissionStore()if(userStore.token){if(to.path/login){next({path:/})}else{// 核心逻辑已登录但尚未生成动态路由if(!permissionStore.isRoutesGenerated){try{// 1. 获取用户信息包含角色/权限awaituserStore.fetchUserInfo()// 2. 生成可访问的路由表constaccessRoutespermissionStore.generateRoutes(userStore.roles)// 3. 动态挂载到路由实例accessRoutes.forEach(route{router.addRoute(route)})// 4. ️ 必须重新导航否则新添加的路由不会立即生效next({...to,replace:true})}catch(error){// 获取用户信息失败如 Token 过期重置状态并跳转登录awaituserStore.logout()next(/login?redirect${to.path})}}else{next()}}}else{// 未登录if(whiteList.indexOf(to.path)!-1){next()}else{next(/login?redirect${to.path})}}})exportdefaultrouter三、 进阶后端返回路由表模式如果后端直接返回路由 JSON 结构如component: system/user/index只需修改generateRoutes中的组件解析逻辑// 后端返回的数据结构示例// { path: /system, component: DEFAULT_LAYOUT, children: [{ path: user, component: system/user/index }] }functionmapBackendRoutes(serverRoutes:any[]):RouteRecordRaw[]{returnserverRoutes.map(item{constroute:any{...item}// 处理布局组件if(item.componentDEFAULT_LAYOUT){route.component()import(/layouts/DefaultLayout.vue)}elseif(item.component){// 动态匹配 views 下的组件constcomponentPath/src/views/${item.component}.vueroute.componentmodules[componentPath]}// 递归处理子路由if(item.children){route.childrenmapBackendRoutes(item.children)}returnroute})}四、 避坑指南刷新白屏/404确保在beforeEach中调用了next({ ...to, replace: true })因为addRoute不会触发当前页面的重新渲染。404 路由位置/:pathMatch(.*)*必须在动态路由全部添加完毕后才生效。如果一开始就写在静态路由里会导致动态路由还没加载就被 404 拦截。Vite 路径匹配import.meta.glob返回的 key 是绝对路径如/src/views/user/index.vue拼接时注意不要漏掉/src/前缀。路由 Name 唯一性动态路由的name必须全局唯一否则addRoute会覆盖同名路由导致页面错乱。

相关新闻

DCIM管理系统的全面剖析与数据中心智能优化实践

DCIM管理系统的全面剖析与数据中心智能优化实践

DCIM管理系统背景与发展概览 随着数据中心规模的迅速扩大和对运营效率要求的提高,DCIM(数据中心基础设施管理)管理系统应运而生。其设计为了为数据中心提供全面的监控与管理解决方案、整合设施管理、资源分配与能耗优化多项功能。从早期的独立…

2026/7/22 14:21:15 阅读更多 →
鸿蒙Flutter 页面间返回值传递:数据回传机制详解

鸿蒙Flutter 页面间返回值传递:数据回传机制详解

引言 在Flutter开发中,页面间的数据传递是一个常见需求。除了从首页传递数据到详情页外,很多场景下还需要从子页面返回数据到父页面。本文将深入探讨Flutter中页面间返回值传递的机制,包括基础用法、高级应用以及最佳实践,帮助开发…

2026/7/22 14:21:15 阅读更多 →
C++ Winsock实战:构建局域网游戏通信框架与TCP Socket编程指南

C++ Winsock实战:构建局域网游戏通信框架与TCP Socket编程指南

1. 项目概述:从零构建一个可玩的局域网游戏通信框架 如果你是一名C开发者,或者对游戏开发背后的网络通信机制充满好奇,那么“用Winsock和Socket实现一个局域网多人游戏”这个项目,绝对是一个能让你从理论跨越到实战的绝佳练手机会…

2026/7/22 14:21:15 阅读更多 →

最新新闻

Python 函数大白话讲解!新手一次搞懂形参、*args、lambda

Python 函数大白话讲解!新手一次搞懂形参、*args、lambda

前言 开始学 Python 的时候,函数这块给我整懵了。 分不清形参实参,看不懂*args和**kwargs,匿名函数 lambda 也一头雾水。 今天用最简单的话来讲,不整难懂术语,代码全都能直接运行。 1. 到底什么是函数? …

2026/7/23 3:24:33 阅读更多 →
C#中HashTable相关方法

C#中HashTable相关方法

C#中的哈希表(HashTable)是由一些列哈希代码组构起的键值对,用于提高访问元素的效率,可以使用键来访问值,键和值都属于Object类型的变量,它同样提供增删查改和多种遍历操作。using System; using System.Co…

2026/7/23 3:24:33 阅读更多 →
C#中Queue相关方法

C#中Queue相关方法

C#中的队列(Queue)本质上是一个Object数组,并为其添加了“先进先出”的元素存取规则,还提供了多种多样的操作方法。using System; using System.Collections;namespace lesson03 {class Program{static void Main(string[] args){…

2026/7/23 3:24:33 阅读更多 →
YoloV5目标检测框架核心代码解析与工程实践

YoloV5目标检测框架核心代码解析与工程实践

1. YoloV5开源项目概述YoloV5作为当前最流行的目标检测框架之一,其官方开源代码以其优异的性能和简洁的架构设计广受开发者青睐。不同于早期Yolo系列的黑盒式实现,YoloV5的代码结构采用了模块化设计理念,每个功能组件都有清晰的边界定义。官方…

2026/7/23 3:24:33 阅读更多 →
CDN技术解析:加速、安全与HTTPS优化实践

CDN技术解析:加速、安全与HTTPS优化实践

1. CDN基础概念与核心价值CDN(Content Delivery Network)本质上是一个分布式服务器网络,它通过将网站内容缓存到全球各地的边缘节点,使用户能够从最近的节点获取数据。这种架构带来的最直接好处是显著降低延迟——根据Akamai的研究…

2026/7/23 3:24:33 阅读更多 →
别再一张张截图了:微信聊天记录导出,取证有效的5种方法!

别再一张张截图了:微信聊天记录导出,取证有效的5种方法!

说一个冷知识:微信聊天属于法定电子证据 但是呢,如果是乱截图、或者是自带录屏是很容易被质疑“篡改、删减、无法合适原始载体”,最后丧失法律效力。 一、聊天记录核心取证原则 要使聊天记录成为“呈堂证供”,必须满足真实性、完…

2026/7/23 3:23:33 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻