Vue3:动态路由+子页面(新增、详情页)动态路由配置(代码全注释)

文章目录

    • 实现思路
    • 调用后端接口获取用户权限
    • 获取页面权限动态绑定到路由对象中
    • 动态添加子页面路由
       

实现思路

   emm,项目中使用动态路由实现根据后端返回的用户详情信息,动态将该用户能够访问的页面信息,动态生成并且绑定到路由对象中。但是后端返回的不包含像是页面详情页,新增页的权限路由,如果前端在路由对象中写死的话,那每次进入页面都得判断是否将进入一个用户没有权限的页面,但是路由中有存在的。所以就想着自己能不能根据后端现有返回的信息,前端自己生成类似详情之类的动态路由。

调用后端接口获取用户页面权限动态绑定到路由对象中

1.获取用户权限

async function getUserAuthority(ids:any) {let userAuthority = nulllet NewList = null//定义请求参数let params = {id:ids,permission_tree:1}//请求用户的信息await get('/system/user/detail',params).then(res=>{if(res.status_code == 200){//userAuthority  存入查询到该用户信息 userAuthority = res.data//模拟该页面是需要跳转其他项目的地址let list =[{id: 119,children:[{id:1191,children:[],parent_id:119,name :'审单管理',slug:'web-system-exchangegoods-management',web_path : `/gongdan`,links:'https://blog.csdn.net/qq_45061461?type=lately'}],slug:'web-system-examineadocument',web_icon:'el-icon-coin',name :'审单管理',web_path: null,},{id: 117,children:[{children:[],id:1171,parent_id:117,slug:'web-system-exchangegoods-management',name :'换货留言列表',web_path : `/gongdan`,links:'https://so.csdn.net/so/search?q=vue3%3Amian,ts%E4%B8%AD%E8%8E%B7%E5%8F%96import.meta.glob&t=&u=&urw='}],slug:'web-system-exchangegoods',web_icon:'el-icon-coin',name :'换货留言列表',web_path: null,}]//将后端返回的用户信息中的权限 和 自己定义的权限对象 合并一起NewList = userAuthority.permissions.concat(list);//将用户的权限信息保存本地中sessionStorage.setItem('NavList',JSON.stringify(NewList))}})return NewList
}

 2.用户登录请求信息 方法我就不写了

//调用定义的获取权限方法
proxy.$PublicAPI.getUserAuthority(list.user_id).then((res) => {//res就是上个方法中返回的权限信息 然后调用将路由添加入路由对象的方法proxy.$PublicAPI.getRouteAddList();//获取默认第一菜单的一个页面的路径进行跳转proxy.$PublicAPI.getOnePagePath();});

3.调用动态追加路由对象的方法

async function getRouteAddList() {<!--定义存放路由信息对象-->let parentRoute = null;<!--判断本地中是否存在权限信息-->if (sessionStorage.getItem('NavList')) {//list是 forEachRout方法返回的数据,将本地权限信息传入,根据信息生成路由对象格式数据let list =  forEachRout() <!--router.getRoutes().find(route => route.name === 'index') 查找路由对象中的路由信息中name名为index的路由对象,name = index的路由对象path指向 index.vue 有显示页面元素的路由视图 <router-view /> -->parentRoute = router.getRoutes().find(route => route.name === 'index');<!--想自己生成的路由对象格式数据 追加到 /index中的chilrend中 -->list.forEach(item => {parentRoute.children.push(item);});<!--将定义好的路由数据格式对象添加到路由对象中-->router.addRoute(parentRoute);}
}

4.设计路由对象格式数据 forEachRout方法

function forEachRout  (){//存放已经设计好的路由对象let list = [] //查找 ../../views/ 文件夹下所有的文件 views文件夹下是我存放的vue文件const module = import.meta.glob("../../views/**");<!-- 获取本地的权限信息 -->let params = JSON.parse(sessionStorage.getItem('NavList'));<!-- 循环遍历权限信息 -->params.forEach(item => {<!-- 判断权限信息中web_path 是否是为string,为string类型就是用户的页面权限 这是后端返回的 -->if (typeof item.web_path === 'string') {<!-- 设计路由对象格式信息 -->let routerChildrenOne = {path: item.web_path,name: `${item.web_path}`,component: module[`../../views${item.web_path}/index.vue`],meta: {title: item.name,buts: [],requireAuth: true,keepAlive: true,externalLink: item.links,}};<!-- 处理好的路由对象格式信息保存起来,后面存入路由对象中 -->list.push(routerChildrenOne);let butOne = item.slug;routerChildrenOne.meta.buts.push(butOne);} 
<!--  这个else 是判断是否需要跳转外部链接的对象,就是第一个截图中定义的两个权限数据对象 
-->
else {item.children.forEach(Citem => {let routerChildren = { <!-- 判断对象中是否存在 links(跳转链接)属性,为存在的话,那么这个path将和其他同样存在links属性的对象公用一个页面(所有需要跳转外部的菜单都共同跳转这一个页面,所以这里使用了路由传参来确定点击他们不会只获取到最近的一个需要外部跳转的菜单,否则菜单中存在一个以上跳转外部菜单,无论点击哪一个都会跳转同一个外部链接。并菜单包含此path全部高亮),就会存在下方截图的错误-->path:Citem.links ? `${Citem.web_path}/:${Citem.id}` :  Citem.web_path ,name: `${Citem.web_path}`,component: module[`../../views${Citem.web_path}/index.vue`],meta: {title: Citem.name,buts: [],requireAuth: true,keepAlive: true,externallink:Citem.links}};list.push(routerChildren);Citem.children.forEach(C_item_C => {let but = C_item_C.slug;routerChildren.meta.buts.push(but);});});}});//返回定义好的路由格式对象return list
}

所以,在配置路由格式对象中外部跳转链接菜单通过动态路由传参来避免出现这个问题.到此菜单的动态路由已经配置完成。

动态添加子页面路由

但是我在想如果每个页面中都存在类似新增和详情的子页面,但是后端返回的信息中未包含,自己怎么也解决动态生成。于是就回到了,后端目前返回给我的权限信息,还有获取到veiws文件夹中的vue文件。

 1.后端返回的权限

2.veiws文件夹中已经存在的

3.实现,此方法就是 P4代码片段的方法 只不过增加了几个变量和调用了几个方法:

 新增变量名:Eligiblelimitsofauthority  , aa

 新增调用方法的方法名:UpdataRouterList 、GetPossibleDetails 

 已经底部retrun之前的判断对象是否存在component绑定的文件路由属性

function forEachRout  (){//存放已经设计好的路由对象let list = []<!-- 存放可能是新增页面,详情页面 和编辑页面的标识 -->let Eligiblelimitsofauthority = []<!-- 存放可能是新增页面,详情页面 和编辑页面的路由对象>let aa = [] //查找 ../../views/ 文件夹下所有的文件 views文件夹下是我存放的vue文件const module = import.meta.glob("../../views/**");<!-- 获取本地的权限信息 -->let params = JSON.parse(sessionStorage.getItem('NavList'));<!-- 筛选出页面中出现可能是新增、详情或者编辑的信息 --> UpdataRouterList(params,Eligiblelimitsofauthority)<!-- 根据传递过来的可能是详情或者编辑的信息,筛选出存在权限的数据,转换成路由格式对象 -->aa =  GetPossibleDetails(Eligiblelimitsofauthority,params,aa)<!-- 循环遍历权限信息 -->params.forEach(item => {<!-- 判断权限信息中web_path 是否是为string,为string类型就是用户的页面权限 这是后端返回的 -->if (typeof item.web_path === 'string') {<!-- 设计路由对象格式信息 -->let routerChildrenOne = {path: item.web_path,name: `${item.web_path}`,component: module[`../../views${item.web_path}/index.vue`],meta: {title: item.name,buts: [],requireAuth: true,keepAlive: true,externalLink: item.links,}};<!-- 处理好的路由对象格式信息保存起来,后面存入路由对象中 -- >list.push(routerChildrenOne);let butOne = item.slug;routerChildrenOne.meta.buts.push(butOne);} 
<!--  这个else 是判断是否需要跳转外部链接的对象,就是第一个截图中定义的两个权限数据对象 
-->
else {item.children.forEach(Citem => {let routerChildren = { <!-- 判断对象中是否存在 links(跳转链接)属性,为存在的话,那么这个path将和其他同样存在links属性的对象公用一个页面(所有需要跳转外部的菜单都共同跳转这一个页面,所以这里使用了路由传参来确定点击他们不会只获取到最近的一个需要外部跳转的菜单,否则菜单中存在一个以上跳转外部菜单,无论点击哪一个都会跳转同一个外部链接。并菜单包含此path全部高亮),就会存在下方截图的错误-->path:Citem.links ? `${Citem.web_path}/:${Citem.id}` :  Citem.web_path ,name: `${Citem.web_path}`,component: module[`../../views${Citem.web_path}/index.vue`],meta: {title: Citem.name,buts: [],requireAuth: true,keepAlive: true,externallink:Citem.links}};list.push(routerChildren);Citem.children.forEach(C_item_C => {let but = C_item_C.slug;routerChildren.meta.buts.push(but);});});}});<!-- 判断转换成路由格式数据中component有数据的对象,component不为空的时候就是标识项目中已经创建了这个新增,详情 或编辑的页面-->if(aa){aa.map(item=>{if(item.component != undefined)list.push(item)})}//返回定义好的路由格式对象return list
}

2.UpdataRouterList方法 筛选出页面中出现可能是详情或者编辑的信息

//筛选出页面中出现可能是详情或者编辑的信息
function UpdataRouterList(navlist:any,Eligiblelimitsofauthority:any) {<!-- 循环传过来的本地权限数据对象中包含了 'create','edit' 和 'detail'的标识 -->navlist.map(item=>{if(item.slug.indexOf('create') != -1 || item.slug.indexOf('edit') != -1 || item.slug.indexOf('detail') != -1){<!-- 存入到可能包含新增,详情,编辑的标识数组中 -->Eligiblelimitsofauthority.push(item.slug)}<!-- 判断是否还有子数据,第一次循环的是下拉菜单 第二次循环的是下拉菜单中的点击跳转页面的菜单,第三次循环点击跳转页面的菜单中的 按钮权限,主要是拿到按钮权限菜单  这里是只有二级菜单,所以循环了三次,如果有多级也会一直循环下去,知道children中没有数据-->>if(item.children){UpdataRouterList(item.children,Eligiblelimitsofauthority)}})
}

3.GetPossibleDetails 根据传递过来的信息,筛选出存在权限的数据, 转换成路由信息,因为如果在本地中已经定义了全部的页面新增,详情,编辑等页面,但是咱们还是需要根据后端返回的权限中,判断咱们是否注册该页面的路由。

//根据传递过来的信息,筛选出存在权限的数据, 转换成路由信息 
function GetPossibleDetails(data:object,navlist:object,aa:any,) {<!-- 获取项目中views文件夹下的所有vue文件 -->const module = import.meta.glob("../../views/**");<!-- 遍历本地中的权限数据-->navlist.map(item=>{<!-- 传递过来的可能是 新增,详情,编辑的权限标识 -->data.map(ditem =>{<!-- 判断 item.web_path是否不为空,如果为空的话表明菜单是下拉菜单就不做操作 item.slug :这个菜单的标识 如:web-users 就是表示user(用户)菜单 -->if(item.web_path != null && ditem == `${item.slug}-create` || ditem == `${item.slug}-edit` ||  ditem == `${item.slug}-detail`){<!-- 存放定义的路由数据格式对象 -->let list = {}<!-- 截取item.we_path 菜单路径处理后的值,如:/user 我拿取user 后面作为/veiws/user,匹配views下的user文件夹 所以这里获取的是该菜单存放的文件夹名称 -->let path  = ''if(item.web_path != null){<!-- 截取文件夹名称 -->path = item.web_path.slice(item.web_path.lastIndexOf('/') + 1 , item.web_path.length)<!-- ditem是方法接收传递过来可能是新增,编辑,详情的权限标识数组,判断最后的-符号的后面是 'create':新增 ,'edit' :编辑 'detail':详情 -->switch ( ditem.slice(ditem.lastIndexOf('-') + 1 , ditem.length)) {case 'create'://如果是新增list = {//定义新增页面跳转的路由路径,如: path是截取到的文件名:user  那就path最后就是 :/usercreatepath: '/'+path + 'create',name: `${path}create`,<!-- 匹配本地vue文件中是否包含 module:views下所有的vue文件,path:文件夹名称,item.web_path:vue文件名称 -->component: module[`../../views/${path}${item.web_path}create.vue`],meta: {title: '新建' + item.name ,buts: [],requireAuth: true,keepAlive: true,externalLink: item.links,}}break;case 'edit':console.log('item-edit',item);list = {path: '/'+path + 'edit',name: `${path}edit`,component: module[`../../views/${path}${item.web_path}edit.vue`],meta: {title: item.name  + '编辑' ,buts: [],requireAuth: true,keepAlive: true,externalLink: item.links,}}break;case 'detail':list = {path: '/'+path + 'detail',name: `${path}detail`,component: module[`../../views/${path}${item.web_path}detail.vue`],meta: {title:  item.name + '详情'  ,buts: [],requireAuth: true,keepAlive: true,externalLink: item.links,}}break;}}aa.push(list)}})<!-- 判断菜单中的chidren是否存在数据,如果没有存在就表明是一级点击跳转菜单,parent_id :0 表示的是菜单 -->if(item.children && item.parent_id == 0){GetPossibleDetails( data,item.children,aa)}})return aa
}

小结

1.最后添加到路由对象中的数据,最后一个对象就是新增的动态子页面路由

项目文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/332869.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】实现贪吃蛇--项目实践(超详细)

前言&#xff1a; 贪吃蛇游戏大家都玩过吧&#xff1f;这次我们要用C语言来亲手制作一个&#xff01;这个项目不仅能让我们复习C语言的知识&#xff0c;还能了解游戏是怎么一步步做出来的。我们会一起完成蛇的移动、食物的生成&#xff0c;还有碰撞检测等有趣的部分。准备好了…

客服快捷回复话术分享:618议价话术和催发货话术

随着618活动大促的临近&#xff0c;客服小伙伴们将迎来一年中最繁忙的时刻。面对顾客的议价、催发货等需求&#xff0c;我们应该如何回复才能既满足顾客的需求&#xff0c;又能保持良好的服务形象呢&#xff1f;下面就为大家分享一些议价和催发货的快捷回复话术&#xff0c;希望…

55页PDF|人工智能通用大模型(ChatGPT)的进展、风险与应对(附下载)

&#x1f449;获取方式&#xff1a; &#x1f61d;有需要的小伙伴&#xff0c;可以保存图片到wx扫描二v码免费领取【保证100%免费】&#x1f193;

WIFI国家码设置的影响

记录下工作中关于国家码设置对WIFI的影响&#xff0c;以SKYLAB的SKW99和SDZ202模组为例进行说明。对应到日常&#xff0c;就是我们经常提及手机是“美版”“港版”等&#xff0c;它们的wifi国家码是不同的&#xff0c;各版本在wifi使用中遇到的各种情况与下面所述是吻合的。 现…

从alpine构建预装vcpkg的docker image用于gitea actions CI

动机 想要构建一个基于vcpkg的交叉编译容器平台用于cpp项目的CI(自动集成),此处仅提供最基础的image,amd64的机子上构建完成后大小为533兆(着实不小😓),各位看官可以在此基础上自行构建需要的版本。 hello world效果展示 corss_compiler.dockerfile FROM alpine:la…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文件系统的磁盘空间使…

springboot 集成 es--未完结

基于es7.10.x版本 一、前提知识 常见的两种方式&#xff1a;spring boot提供的API 和 ES 官方提供的API ES官方&#xff1a; RestHighLevelClient&#xff1a; 适用于复杂、更细粒度控制的Elasticsearch 操作 spring boot&#xff1a; ElasticsearchRestTemplate&#xff1a…

linux查看是否被入侵(一)

1、查看当前系统状态 [rootbastion-IDC ~]#top #一般挖矿等病毒点用CPU比较大 2、查看当前登录用户(w\who) 3、检查系统日志 检查系统错误登陆日志&#xff0c;统计IP重试次数 [rootbastion-IDC ~]# lastb 4、查看近期用户登录情况 [rootkvm01 ~]# last -n 5 #-n 5 表示…

软件3班20240527

JDK 版本与 Tomcat 的 兼容性

nginx流量监控:goAccess安装与使用

关于goAccess GoAccess 是一款实时、快速的日志分析工具&#xff0c;专门设计用于分析Web服务器日志&#xff0c;特别是Nginx日志。 安装 &#xff08;1&#xff09;准备相关依赖 # Missing development libraries for ncursesw # centOS yum install -y ncurses-devel # U…

【EI会议】2024年互联网技术与环境工程国际会议(IACITEE 2024)

【EI会议】2024年互联网技术与环境工程国际会议&#xff08;IACITEE 2024&#xff09; 2024 International Conference on Internet Technology and Environmental Engineering 互联网技术与环境工程国际会议&#xff08;IACITEE 2024&#xff09;将在重庆举行&#xff0c;主…

怎么把记事本钉在桌面上 桌面记事本固定不动的方法

我的生活&#xff0c;总是被密密麻麻的待办事项和灵感想法填得满满当当。记事本&#xff0c;就是我随身的记忆银行&#xff0c;帮我存储那些稍纵即逝的思维火花和不能错过的琐事提醒。每当翻开那一页页工整的笔记&#xff0c;心中的焦虑和压力似乎都找到了释放的出口。 但一直…

锐捷网络与您相约第七届数字中国建设峰会 共话数字未来

第七届数字中国建设峰会将于5月24日至25日在福建福州举办,本届峰会是国家数据工作体系优化调整后首次举办的数字中国建设峰会,主题是“释放数据要素价值,发展新质生产力”。作为行业领先的ICT基础设施及解决方案提供商,锐捷网络与福建省电子信息集团、星网锐捷,围绕“发展新质生…

mvc的常见注解

问文心一言的&#xff0c;记录一下。 PathVariable 路径变量注解 PathVariable 是 Spring MVC 提供的一个注解&#xff0c;它用于从 URI 模板变量中绑定值到控制器方法的参数上。当你在 RequestMapping、GetMapping、PostMapping、PutMapping、DeleteMapping 等注解的 URL 路…

基于深度学习和opencv的车牌识别系统

免费获取方式↓↓↓ 项目介绍028&#xff1a; 基于深度学习和opencv的车牌识别系统 同时利用对图片每一帧图像加入视频分析模块 图片分析模块可以依据界面按钮提示进行相应功能 视频分析模块可以根据按钮提示进行对视频的分析 &#xff08;视频模块的视频追踪处理时间较长&…

跨平台之用VisualStudio开发APK嵌入OpenCV(一)

序 本篇是杂谈以及准备工作&#xff08;此处应无掌声&#xff09; 暂时不管iOS&#xff08;因为开发hello world都要年费&#xff09; 软件&#xff1a; Visual Studio 2019&#xff08;含Android SDK和NDK编译器等&#xff09; OpenCV 这是一个女仆级的系列文章&#xf…

Lookin高效调试iOS App的UI

Lookin是一款iOS开发时常用的调试软件&#xff0c;由腾讯微信读书团队QMUI开发。 它可以查看和修改iOS App里的UI对象的软件&#xff0c;展示App UI图层&#xff0c;类似于Xcode自带的UI Inspector工具&#xff0c;或另一款叫做Reveal的软件。 此外&#xff0c;虽然Lookin主体…

半年不在csdn写博客,总结一下这半年的学习经历,coderfun的一些碎碎念.

前言 自从自己建站一来&#xff0c;就不在csdn写博客了&#xff0c;但是后来自己的网站因为资金问题不能继续维护下去&#xff0c;所以便放弃了自建博客网站来写博客&#xff0c;等到以后找到稳定&#xff0c;打算满意的工作再来做自己的博客网站。此篇博客用来记录自己在csdn…

PyTorch深度学习快速入门——P1-P13

环境配置 Anaconda&#xff0c;创建conda create -n pytorch python3.12&#xff0c;使用conda activate pytorch切换到环境。安装pytorch&#xff0c;conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia&#xff0c;使用import torch&…

飞机类设计与实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、飞机类属性的定义 三、飞机类方法的创建 四、面向对象的封装特性 五、代码…