解析路由表,生成结构化数据
2022/4/20 6:13:44
本文主要是介绍解析路由表,生成结构化数据,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
如果我们需要创建后台管理系统的动态菜单(根据权限显示对应的选项),需要获取路由表的数据信息
想要获取路由表数据,那么有两种方式:
- router.options.routes:初始路由列表(无法获取到新增的路由)
- router.getRoutes():获取所有 路由记录 的完整列表
因为方式1的特性有缺陷,因此我们使用方式2获取到路由表
使用router.getRoutes()获取到的路由表信息如下:
[ { "path":"/user/info/:id", "name":"userInfo", "meta":{ "title":"userInfo" }, "children":[ ] }, { "path":"/user/manage", "meta":{ "title":"userManage", "icon":"personnel-manage" }, "children":[ ] }, { "path":"/user/role", "meta":{ "title":"roleList", "icon":"role" }, "children":[ ] }, { "path":"/user/permission", "meta":{ "title":"permissionList", "icon":"permission" }, "children":[ ] }, { "path":"/user/import", "name":"import", "meta":{ "title":"excelImport" }, "children":[ ] }, { "path":"/login", "meta":{ }, "children":[ ] }, { "path":"/profile", "name":"profile", "meta":{ "title":"profile", "icon":"el-icon-user" }, "children":[ ] }, { "path":"/404", "name":"404", "meta":{ }, "children":[ ] }, { "path":"/401", "name":"401", "meta":{ }, "children":[ ] }, { "path":"/user", "redirect":"/user/manage", "meta":{ "title":"user", "icon":"personnel" }, "children":[ { "path":"/user/manage", "meta":{ "title":"userManage", "icon":"personnel-manage" } }, { "path":"/user/role", "meta":{ "title":"roleList", "icon":"role" } }, { "path":"/user/permission", "meta":{ "title":"permissionList", "icon":"permission" } }, { "path":"/user/info/:id", "name":"userInfo", "meta":{ "title":"userInfo" } }, { "path":"/user/import", "name":"import", "meta":{ "title":"excelImport" } } ] } ]
由上,可以看出,它是一个一级路由与二级路由位于数组同一层级的数据结构,这不符合我们的需求,我们需要的是一个一级路由内包括二级路由的数据结构,类似于树结构的数据结构,它需要符合如下特点:
- 满足该条件 meta && meta.title && meta.icon
- 一级路由二级路由应该是树形嵌套
[ { "path":"/profile", "name":"profile", "meta":{ "title":"profile", "icon":"el-icon-user" }, "children":[ ] }, { "path":"/user", "redirect":"/user/manage", "meta":{ "title":"user", "icon":"personnel" }, "props":{ "default":false }, "children":[ { "path":"/user/manage", "meta":{ "title":"userManage", "icon":"personnel-manage" }, "children":[ ] }, { "path":"/user/role", "meta":{ "title":"roleList", "icon":"role" }, "children":[ ] }, { "path":"/user/permission", "meta":{ "title":"permissionList", "icon":"permission" }, "children":[ ] } ], "instances":{ }, "leaveGuards":{ }, "updateGuards":{ }, "enterCallbacks":{ }, "components":{ "default":{ "__scopeId":"data-v-13877386", "__hmrId":"13877386", "__file":"src/layout/index.vue" } } }, { "path":"/article", "redirect":"/article/ranking", "meta":{ "title":"article", "icon":"article" }, "props":{ "default":false }, "children":[ { "path":"/article/ranking", "meta":{ "title":"articleRanking", "icon":"article-ranking" }, "children":[ ] }, { "path":"/article/create", "meta":{ "title":"articleCreate", "icon":"article-create" }, "children":[ ] } ], "instances":{ }, "leaveGuards":{ }, "updateGuards":{ }, "enterCallbacks":{ }, "components":{ "default":{ "__scopeId":"data-v-13877386", "__hmrId":"13877386", "__file":"src/layout/index.vue" } } } ]
因此,我们需要对它进行解析
utils/route.js
import path from 'path' /** * 返回所有子路由 */ const getChildrenRoutes = routes => { const result = [] routes.forEach(route => { if (route.children && route.children.length > 0) { result.push(...route.children) } }) return result } /** * 处理脱离层级的路由:某个一级路由为其他子路由,则剔除该一级路由,保留路由层级 * @param {*} routes router.getRoutes() */ export const filterRouters = routes => { const childrenRoutes = getChildrenRoutes(routes) return routes.filter(route => { return !childrenRoutes.find(childrenRoute => { return childrenRoute.path === route.path }) }) } /** * 判断数据是否为空值 */ function isNull(data) { if (!data) return true if (JSON.stringify(data) === '{}') return true if (JSON.stringify(data) === '[]') return true return false } /** * 根据 routes 数据,返回对应 menu 规则数组 */ export function generateMenus(routes, basePath = '') { const result = [] // 遍历路由表 routes.forEach(item => { // 不存在 children && 不存在 meta 直接 return if (isNull(item.meta) && isNull(item.children)) return // 存在 children 不存在 meta,进入迭代 if (isNull(item.meta) && !isNull(item.children)) { result.push(...generateMenus(item.children)) return } // 合并 path 作为跳转路径 const routePath = path.resolve(basePath, item.path) // 路由分离之后,存在同名父路由的情况,需要单独处理 let route = result.find(item => item.path === routePath) if (!route) { route = { ...item, path: routePath, children: [] } // icon 与 title 必须全部存在 if (route.meta.icon && route.meta.title) { // meta 存在生成 route 对象,放入 arr result.push(route) } } // 存在 children 进入迭代到children if (item.children) { route.children.push(...generateMenus(item.children, route.path)) } }) return result }
生成符合动态menu要求的结构化数据:
import { computed } from 'vue' import { useRouter } from 'vue-router' import { filterRouters, generateMenus } from '@/utils/route' const router = useRouter() // 获取符合动态menu菜单需要的结构化路由表数据 const routes = computed(() => { const filterRoutes = filterRouters(router.getRoutes()) return generateMenus(filterRoutes) })
这篇关于解析路由表,生成结构化数据的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南