Vue权限控制——动态注册路由

需求:实现后台管理系统不同用户的权限控制

在这里插入图片描述
根据登录的用户的角色动态展示后台管理系统的左侧菜单栏的菜单列表内容,然后还要动态注册对应子菜单的路由
菜单列表内容应该通过后端接口返回:

  1. sort为1表示当前项有子菜单
  2. sort为2表示当前项没有子菜单,这个才是需要我们去动态注册的组件
    在这里插入图片描述
    前端需要根据后端返回的菜单列表去动态的展示菜单列表:
    在这里插入图片描述

并且为每个菜单列表项注册对应的路由:

  1. 在views/main文件夹下创建所有的页面(component)
    在这里插入图片描述

  2. 在router/main文件夹下创建每个页面对应的路由对象(此时只是先配置好路由path和组件component的映射关系,还没有注册路由,后续会根据后端返回的用户菜单表数据(userMenus)动态的去注册路由
    在这里插入图片描述
    在这里插入图片描述

  3. 根据用户的角色role.id向后端发送请求,拿到当前登录用户的userMenus菜单
    在这里插入图片描述

在这里插入图片描述

  1. 根据userMenus生成对应的routes
    1)先拿到项目中所有组件的路由对象route放到allRoutes数组中
    2)再递归遍历userMenus数组的每一项(menu),将满足menu.url === route.path条件的menu放到routes数组中
    在这里插入图片描述

  2. 遍历routes数组,把数组中的每一个route通过router.addRoute('main', route),动态注册到main路由对象的children属性中在这里插入图片描述

import type { RouteRecordRaw } from 'vue-router'export function mapMenuToRoutes(userMenus: any[]): RouteRecordRaw[] {const routes: RouteRecordRaw[] = []// 1.先去加载默认所有的routesconst allRoutes: RouteRecordRaw[] = []const routeFiles = require.context('../router/main', true, /\.ts/)routeFiles.keys().forEach((key) => {console.log(key) // ./analysis/dashboard/dashboard.tsconst route = require('../router/main' + key.split('.')[1])allRoutes.push(route.default)})console.log(allRoutes)// 2.根据菜单获取需要添加到routesconst _recurseGetRoute = (menus: any[]) => {for (const menu of menus) {if (menu.type === 2) {const route = allRoutes.find((route) => {return route.path === menu.url})if (route) routes.push(route)} else {_recurseGetRoute(menu.children)}}}_recurseGetRoute(userMenus)return routes
}
<template><div class="nav-menu"><div class="logo"><img src="~@/assets/img/logo.svg" alt="logo" /><span class="title" v-if="!collapse">后台管理系统</span></div><el-menudefault-active="1":collapse="collapse"class="el-menu-vertical"background-color="#0c2135"text-color="#b7bdc3"unique-openedactive-text-color="#0a60bd"><template v-for="item in userMenus" :key="item.id"><!-- 有二级菜单的一级菜单 --><template v-if="item.type === 1"><!-- 一级菜单 --><el-sub-menu :index="item.id + ''"><template #title><el-icon><Setting /></el-icon><!-- <i v-if="item.icon" :class="item.icon"></i> --><span>{{ item.name }}</span></template><template v-for="subItem in item.children" :key="subItem.id"><!-- 二级菜单  --><el-menu-item:index="subItem.id + ''"@click="handleMenuItemClick(subItem)"><i v-if="subItem.icon" :class="subItem.icon"></i><span>{{ subItem.name }}</span></el-menu-item></template></el-sub-menu></template><!-- 没有二级菜单的一级菜单 --><template v-else-if="item.type === 2"><!-- 一级菜单 --><el-menu-item :index="item.id + ''"><i v-if="item.icon" :class="item.icon"></i><span>{{ item.name }}</span></el-menu-item></template></template></el-menu></div>
</template><script lang="ts">
import { defineComponent, computed } from 'vue'
import { Setting } from '@element-plus/icons-vue'
import { useStore } from '@/store'
import { useRouter } from 'vue-router'
export default defineComponent({name: 'nav-menu',components: { Setting },props: {collapse: {type: Boolean,default: false}},setup(props, context) {const store = useStore()const router = useRouter()const userMenus = computed(() => store.state.login.userMenus)const handleMenuItemClick = (item: any) => {// console.log(item)router.push({path: item.url ?? '/not-found'})}return {userMenus,handleMenuItemClick}}
})
</script><style scoped lang="less">
.nav-menu {height: 100%;background-color: #001529;
}
.logo {display: flex;height: 28px;padding: 12px 10px 8px 10px;flex-direction: row;justify-content: center;align-items: center;img {width: 40px;height: 40px;}.title {font-size: 16px;font-weight: 700;color: #fff;}
}
.el-menu-vertical {width: 100%;height: calc(100% - 48px);
}
.el-menu {border-right: none;
}
</style>

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

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

相关文章

react不同环境不同配置angular_前端问题集:vue配置环境-给不同的环境配不同的打包命令...

通过vue-cli脚手架构建出一个前端项目&#xff0c;通过npm run build打包&#xff0c;发布到线上&#xff0c;但是这样做需要每次都手动修改接口地址。我们可以通过自行配置打包命令实现无需修改接口地址&#xff0c;打各个环境的包。文档结构大致如下图&#xff1a;1.找到conf…

基于Element-plus封装配置化表单组件(组件的v-model实现)

一、预备知识 1.1 组件的v-model 前面我们在input中可以使用v-model来完成双向绑定&#xff1a; 这个时候往往会非常方便&#xff0c;因为v-model默认帮助我们完成了两件事&#xff1b;v-bind:value的数据绑定 和 input的事件监听&#xff1b; 如果我们现在封装了一个组件…

Scala IDE for Eclipse的下载、安装和WordCount的初步使用(本地模式和集群模式)

不多说&#xff0c;直接上干货&#xff01; 这篇博客是&#xff0c; 是在Scala IDEA for Eclipse里maven创建scala和java代码编写环境。 Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境&#xff08;图文详解&#xff09; 本博文包括&#xff1a; Scala IDE fo…

笔记本AutoCAD启动时闪退怎么办_戴尔笔记本电脑开不了机如何解决【解决方法】...

生活在互联时代下&#xff0c;我们对笔记本的需求是无处不在的&#xff0c;不管是上班族还是学生党&#xff0c;使用笔记本办公和学习给我们的生活带来很大的便捷。但使用的过程中&#xff0c;总有可能会遇到无法预料的问题。比方说 笔记本电脑 无法开机的问题&#xff0c;当…

JS高级——函数执行、作用域链内存结构图

一、JavaScript的执行过程 假如我们有下面一段代码&#xff0c;它在JavaScript中是如何被执行的呢&#xff1f; 1.1 第一步&#xff1a;初始化全局对象 js引擎会在执行代码之前&#xff0c;会在堆内存中创建一个全局对象&#xff1a;Global Object&#xff08;GO&#xff09…

JS高级——内存管理和闭包

0、预备知识 0.1 认识内存管理 不管什么样的编程语言&#xff0c;在代码的执行过程中都是需要给它分配内存的&#xff0c;不同的是某些编程语言需要我们自己手动的管理内存&#xff0c;某些编程语言会可以自动帮助我们管理内存&#xff1a; 不管以什么样的方式来管理内存&…

提取多个字段_【博客翻译】建筑物轮廓线提取以及损坏分类

原文链接原作者&#xff1a;Rohit Singh, Sandeep Kumar贡献者&#xff1a;Vinay Viswambharan, Divyansh Jha, Shivani Pathak, Daniel Wilson.翻译&#xff1a;荆雪涵在今年的 Esri 用户大会上&#xff0c;USAA 展示了基于 ArcGIS 深度学习能力&#xff0c;对 Woolsey 火灾进…

读取外部配置文件_SpringBoot外部配置、优先级及配置详解

一、外部配置及优先级SpringBoot的外部配置属性值官方给出了很多种方式&#xff0c;以便可以在不同的环境中使用相同的代码。其使用了非常特别的PropertySource命令&#xff0c;旨在允许合理的覆盖值。当然&#xff0c;如果属性值不同&#xff0c;则这些配置方式中的属性值都会…

Jquery 禁用浏览器的 后退和前进按钮

使用js,Jquery 禁用浏览器的back 和 next 按钮&#xff1a; 有时为了防治用户乱了访问顺序&#xff0c;不得不禁掉浏览器的前进后退按钮。 jQuery(document).ready(function () {if (window.history && window.history.pushState) {$(window).on(popstate, function ()…

JS数据结构与算法——冒泡排序(把大的数字依次往后放)

一、图解排序过程 注意&#xff1a;比较次数和交换次数之所以不一致&#xff0c;是因为&#xff1a;比较了并不一定就需要交换两个数字的位置&#xff0c;比如比较 1 和 2两个数字&#xff0c;由于 后者本身就比前者大&#xff0c;所以不需要交换两者的位置。 二、代码实现 三…

手机长曝光怎么设置_摄影教程丨手机如何拍摄长曝光照片,流光快门,星空银河搞起来!...

微信搜一搜定格取景框长曝光摄影可以拍摄出一些很酷的照片。这是一种非常灵活的摄影技术。它可以用来拍摄城市夜景&#xff0c;记录光绘&#xff0c;也可以拍摄水景片。甚至可以拍摄银河或捕捉星轨。其实长曝光不仅仅适合专业摄影师&#xff01;任何人都可以用手机进行慢门拍摄…

JS数据结构与算法——选择排序(把小的数字依次往前放)

一、图解排序过程 注意&#xff1a;选择排序一样是需要进行两两的比较&#xff0c;但比较过程中不进行交换&#xff0c;只有比较完成后&#xff0c;找到最小的那个数&#xff0c;才会进行交换&#xff0c;把它放到最前面。 二、代码实现 三、完整代码 <!DOCTYPE html> &…

插入模板_WordPress在文章列表和内容页插入广告

本文已同步到专业技术网站 www.sufaith.com, 该网站专注于前后端开发技术与经验分享, 包含Web开发、Nodejs、Python、Linux、IT资讯等板块.一、在文章列表插入广告文章列表模板 包括以下几个类型以及对应的主体文件:首页模板 (index.php)搜索结果页 (search.php)文章归档 (arch…

JS数据结构与算法——插入排序

一、图解排序过程 二、代码实现 三、完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><script>// 创建列表类function ArrayList() {//…

cad完全卸载教程_CAD室内设计中厨房布置实例

▲ 点击“CAD教学”&#xff0c;获取海量学习资料和免费教程本文介绍CAD室内设计中厨房布置方法&#xff1a;1、如下图是把另一边墙砌好&#xff0c;因为不砌的话门太大的话不好。在煮菜的烟容易在烟到不胜客厅里。2、在用矩形画宽为40长为800的玻璃门。3、在把厨房的台画出来&…

CSS布局(圣杯布局、双飞翼布局、水平垂直居中)

一、圣杯布局 要求&#xff1a;三列布局&#xff1b;中间主体内容前置&#xff0c;且宽度自适应&#xff1b;两边内容定宽 好处&#xff1a;重要的内容放在文档流前面可以优先渲染 原理&#xff1a;利用相对定位、浮动、负边距布局&#xff0c;而不添加额外标签 <!DOCTYPE …

cad怎么设置线的粗细_CAD软件中怎么设置CAD线宽?

在使用CAD软件绘制CAD图纸的过程中&#xff0c;不同线宽的用处是不同的。在机械制图中&#xff0c;零部件的外轮廓就是用粗实线&#xff0c;图形内部的剖开线使用细实线。一般情况下&#xff0c;都是在绘制图形过程中先设置好图形的线宽对象&#xff0c;但也有些需要在后面的绘…

检测范围_论文检测系统的检测范围有哪些

为了能够让研究人员&#xff0c;甚至一些专业的学术专家在进行论文创作的时候&#xff0c;端正自己的学术态度&#xff0c;很多人都会要求他们在提交甚至是发表论文之前&#xff0c;附上自己的查重证明&#xff0c;只有查重率低于一定程度时&#xff0c;提交的论文才是合格的。…

2学习率调整_学习率衰减

之前我们的优化&#xff0c;主要是聚焦于对梯度下降运动方向的调整&#xff0c;而在参数迭代更新的过程中&#xff0c;除了梯度&#xff0c;还有一个重要的参数是学习率α&#xff0c;对于学习率的调整也是优化的一个重要方面。01—学习率衰减首先我们以一个例子&#xff0c;来…

mysql 用户管理表_Mysql—用户表详解(mysql.user)

MySQL数据库Mysql—用户表详解(mysql.user)MySQL是一个多用户管理的数据库&#xff0c;可以为不同用户分配不同的权限&#xff0c;分为root用户和普通用户&#xff0c;root用户为超级管理员&#xff0c;拥有所有权限&#xff0c;而普通用户拥有指定的权限。MySQL是通过权限表来…