【Vue框架】菜单栏权限的使用与显示

前言

在 【Vue框架】Vue路由配置 中的getters.js里,可以看到有一个应用程序的状态(变量)叫 permission_routes,这个就是管理前端菜单栏的状态。具体代码的介绍,都以注释的形式来说明。

1、modules\permission.js

1.1 代码

import { asyncRoutes, constantRoutes } from '@/router'/*** Use meta.role to determine if the current user has permission* @param roles 用户角色* @param route 路由信息*/
function hasPermission(roles, route) {// 判断route是否存在meta和meta.rolesif (route.meta && route.meta.roles) {// 判断当前传入的角色,是否存在路由的route中return roles.some(role => route.meta.roles.includes(role))} else {return true}
}/*** Filter asynchronous routing tables by recursion* 通过 递归 筛选异步路由表* 【将 基础路由(不含角色权限)和 符合用户权限的动态路由(需要角色权限)全部存入res】* @param routes asyncRoutes【去看router\index.js中asyncRoutes】* @param roles*/
export function filterAsyncRoutes(routes, roles) {const res = []// routes是在router\index.js定义的路由数组routes.forEach(route => {const tmp = { ...route } // 数组中遍历获取其中路由对象if (hasPermission(roles, tmp)) { // 判断当前路由是否存在角色if (tmp.children) { // 判断当前路由是否存在二级路由tmp.children = filterAsyncRoutes(tmp.children, roles)}res.push(tmp)}})return res
}// 定义的状态
const state = {routes: [],addRoutes: []
}// 用于存储一系列 改变 应用状态的方法
const mutations = {SET_ROUTES: (state, routes) => {state.addRoutes = routesstate.routes = constantRoutes.concat(routes) // 用户角色的动态路由加入到基础路由中}
}// 用于存储一系列 触发改变 应用状态的方法
const actions = {generateRoutes({ commit }, roles) {return new Promise(resolve => {let accessedRoutesif (roles.includes('admin')) { // 如果roles数组中包含'admin'accessedRoutes = asyncRoutes || [] // 动态路由全部可以访问,如果asyncRoutes为`undefined`或`null`,则取[]} else {accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) // 递归出符合条件的路由}commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}
}
// 默认导出一个对象,包含了模块的相关配置
export default {// 设置模块的命名空间为 `true`,这意味着该模块中的状态、mutations、getters、actions将被封装在命名空间中,以避免和其他模块的冲突namespaced: true,// 模块的状态state,// 模块的变化方法mutations,// 模块的行为方法(调用action,触发mutations,改变state)actions
}

该文件除了定义的routes路由状态和addRoutes动态添加的路由(后续用到的时候在提),主要在actions中定义了生成路由的行为方法generateRoutes,根据roles角色和内置传入的{ commit }context.commit)获取router\index.js中定义的一系列路由,简单说,就是在前端页面上被访问的路径

补充防忘记:

  1. new Promise()以及其参数
  2. 【Vue框架】Vue路由配置 看看路由
  3. 【Vue框架】Vuex状态管理

1.2 想法:

modules\permission.js中,根据generateRoutes提前写好的逻辑来判断查回用户的权限是否符合,这样不利于添加新角色的改动。
应该都得从数据库中查询,得到库中的角色和每个动态路由。(个人猜想,后续在尝试)

2、layout\components\Sidebar

2.1 index.vue

遍历展示整体的菜单栏。

<template><div :class="{'has-logo':showLogo}"><logo v-if="showLogo" :collapse="isCollapse" /><el-scrollbar wrap-class="scrollbar-wrapper"><el-menu:default-active="activeMenu":collapse="isCollapse":background-color="variables.menuBg":text-color="variables.menuText":unique-opened="false":active-text-color="variables.menuActiveText":collapse-transition="false"mode="vertical"><sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" /></el-menu></el-scrollbar></div>
</template><script>
import { mapGetters } from 'vuex' // 从`vuex`库中导入`mapGetters`函数,用于将getter映射到该组件的计算属性中
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'export default {// 在该组件中注册了`SidebarItem`和`Logo`两个组件,以便在模板中使用它们components: { SidebarItem, Logo },// `computed`计算属性中,可以定义一些依赖于其他数据的属性。这些属性的值会根据其依赖的数据动态计算得出,并在依赖数据发生变化时自动更新。// `computed`计算属性的定义方式可以是一个对象,对象的每个属性都是一个计算属性的定义// `...mapGetters([...])`将`mapGetters`返回的映射对象展开并添加到该组件的计算属性中,这样可以直接访问映射的getter// mapGetters([...])里的数组中包含想要映射的getter方法的名称computed: {...mapGetters(['permission_routes','sidebar']),// 根据当前路由对象的元信息(`meta`)中的`activeMenu`属性来确定活动的菜单项。// 如果未设置`activeMenu`属性,则返回当前路径(`path`)activeMenu() {const route = this.$route // `this.$route`是在Vue中访问当前路由的对象(全局属性,只读,不能直接更改路由信息)const { meta, path } = route// if set path, the sidebar will highlight the path you setif (meta.activeMenu) {return meta.activeMenu // 侧边栏将高亮显示设置的路径}return path // 如果未设置`activeMenu`属性,则返回当前路由的路径。侧边栏将根据当前路径高亮显示相应的菜单项},showLogo() {return this.$store.state.settings.sidebarLogo},variables() {return variables},isCollapse() {// 如果`opened`属性为`true`,则`isCollapse`为`false`,表示侧边栏未折叠;// 如果`opened`属性为`false`,则`isCollapse`为`true`,表示侧边栏已折叠return !this.sidebar.opened}}
}
</script>

2.2 SidebarItem.vue

具体遍历显示每一个具体的菜单项。

<template><div v-if="!item.hidden" class="menu-wrapper"><!-- 这的item就是route,onlyOneChild就是当前route下的子菜单 --><!-- 1判断route下是否为01个子菜单 && 2(!当前route下的子菜单是还存在子菜单||子菜单不存在时) &&  3--><!-- 这里的template:当前route下只有1个或0个子菜单,且唯一子菜单下不存在下级菜单时,执行这段代码效果:菜单栏中,该route为一级菜单,不显示其子菜单--><template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"><!-- 其子菜单中存在meta --><app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"><el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"><item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /></el-menu-item></app-link></template><!--  存在多级子菜单的时候  --><el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body><!-- 这里的插槽名为title;作用和上面一样,主要是显示一级菜单,但这里没用app-link让该菜单具有跳转功能 --><template slot="title"><item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /></template><!-- 具体的菜单项,遍历各个子菜单 --><sidebar-itemv-for="child in item.children":key="child.path":is-nest="true":item="child":base-path="resolvePath(child.path)"class="nest-menu"/></el-submenu></div>
</template><script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'export default {name: 'SidebarItem',components: { Item, AppLink },// 通过 `mixins` 可以将一些常用的选项(如 `data`、`methods`、`created` 等)或复杂逻辑封装成可复用的模块,并在多个组件中混入使用mixins: [FixiOSBug],// 用于定义组件的属性。可以是数组、对象或具体的属性定义。通过 props 可以接收组件外部传入的数据,并在组件内部使用props: {// route objectitem: {type: Object,required: true},isNest: {type: Boolean,default: false},basePath: {type: String,default: ''}},data() {// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237// TODO: refactor with render function// 当前route的子菜单this.onlyOneChild = nullreturn {}},methods: {hasOneShowingChild(children = [], parent) {const showingChildren = children.filter(item => {if (item.hidden) {return false} else {// Temp set(will be used if only has one showing child)this.onlyOneChild = itemreturn true}})// 只存在一个子菜单// When there is only one child router, the child router is displayed by defaultif (showingChildren.length === 1) {return true}// 不存在菜单// Show parent if there are no child router to displayif (showingChildren.length === 0) {// 如果没有子菜单显示,将父级菜单的一些属性复制到`onlyOneChild`对象中,同时设置`onlyOneChild`的`path`为空字符串,// 并设置`noShowingChildren`属性为`true`,表示没有子菜单显示。最后返回`true`。this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }return true}// 子菜单存在多个的时候return false},resolvePath(routePath) {// `isExternal(routePath)`函数判断`routePath`是否为外部链接,如果是外部链接,则直接返回`routePath`,不做处理// 当只有唯一子菜单时,`routePath`是子菜单路径if (isExternal(routePath)) {return routePath}// 当只有唯一子菜单时,`basePath`是父级菜单的路径if (isExternal(this.basePath)) {return this.basePath}// `path.resolve()`函数将`this.basePath`和`routePath`拼接成一个完整的路径,并返回该路径// 返回 `/父级菜单的路径/子菜单路径`return path.resolve(this.basePath, routePath)}}
}
</script>

2.3 Link.vue

<template><!-- eslint-disable vue/require-component-is --><component v-bind="linkProps(to)"><slot /></component>
</template><script>
import { isExternal } from '@/utils/validate'export default {props: {to: {type: String,required: true}},methods: {linkProps(url) {if (isExternal(url)) {return {is: 'a', // 标签名href: url, // 链接target: '_blank', // 用于指定链接在哪个窗口或框架中打开,`_blank`在新的标签页中打开链接rel: 'noopener' // 用于指定链接与当前页面之间的关系,当使用`target="_blank"`时,防止新打开的窗口通过`window.opener`属性访问到当前页面的信息,提高安全性。}}return {is: 'router-link', // 标签名to: url}}}
}
</script>

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

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

相关文章

SpringBoot 将项目打包成 jar 包

SpringBoot 将项目打包成 jar 包 一、项目打包成 jar 包 首先在 pom.xml 文件中导入 Springboot 的 maven 依赖 <!-- 将应用打包成一个可以执行的 jar 包 --> <build><plugins><plugin><groupId>org.springframework.boot</groupId><…

学习笔记整理-面向对象-02-认识函数的上下文

一、认识函数的上下文 什么是上下文 垃圾分类&#xff0c;这是非常好的习惯&#xff0c;值得表扬随手关灯&#xff0c;这是非常好的习惯&#xff0c;值得表扬遛狗栓绳&#xff0c;这是非常好的习惯&#xff0c;值得表扬课后复习&#xff0c;这是非常好的习惯&#xff0c;值得…

【数据结构】单链表OJ题(二)

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、链表分割 &#x1f4a1;方法一&#xff1a; 二、链表的回文 &#x…

hosts文件中被添加 windows10.microdone.cn

在网上搜了一圈逗说是之前下过征信中心的安全控件,是微通新成网络科技有限公司这家公司提供的,也是http://microdone.cn的运营商。后边只要使用代理,就会跳出来,所以常规处理操作就是去把浏览器上的安全控件卸载了。 参考 解决 windows10 的 代理频繁被自动篡改为windows10.mi…

利用python实现激光雷达LAS数据滤波的7种方式,使用laspy读写

激光雷达&#xff08;LiDAR&#xff09;数据在实际应用中可能受到噪声和不完美的测量影响&#xff0c;因此数据去噪和滤波方法变得至关重要&#xff0c;以提高数据质量和准确性。以下是一些常用的激光雷达数据去噪与滤波方法。 原始数据如下&#xff1a; 1. 移动平均滤波&…

kubernetes中PV和PVC

目录 一、PV、PVC简介 二、PV、PVC关系 三、创建静态PV 1.配置nfs存储 2.定义PV 3.定义PVC 4.测试访问 四、 搭建 StorageClass nfs-client-provisioner &#xff0c;实现 NFS 的动态 PV 创建 1. 配置nfs服务 2.创建 Service Account 3.使用 Deployment 来创建 NFS P…

Figma中文社区来啦,云端协作设计你准备好了吗?

Figma是改变产品设计协作方式的重要工具,但由于没有中文社区,对国内设计师的约束较大。而拥有全中文UI 界面、功能齐全的即时设计资源广场,恰好弥补了Figma的这一短板,它也将取代Figma成为设计师新宠。 1、UI组件集 Figma中文社区替代即时设计资源广场,拥有海量丰富的UI设计组…

【BEV Review】论文 Delving into the Devils of Bird’s-eye-view 2022-9 笔记

背景 一般来说&#xff0c;自动驾驶车辆的视觉传感器&#xff08;比如摄像头&#xff09;安装在车身上方或者车内后视镜上。无论哪个位置&#xff0c;摄像头所得到的都是真实世界在透视视图&#xff08;Perspective View&#xff09;下的投影&#xff08;世界坐标系到图像坐标系…

ssm柚子云电子商城java图书购物电子商务管理jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 ssm柚子云电子商城 系统有2权限&#xff1a;前台、后…

SpringBoot笔记:SpringBoot 集成 Dataway 多数据源配置(二)

文章目录 前言核心代码和配置yml 配置注入多数据源常用Spi实现swagger 配置自定义 Udf指定数据源进行查询 前言 之前简单介绍了一下 Dataway 使用&#xff0c;本文继续介绍一下它的多数据源配置和使用。 核心代码和配置 yml 配置 # springboot多环境配置 #端口&#xff0c;…

JavaScript应用:五子棋游戏实战开发

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…

面试热题(螺旋矩阵)

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素 一看到这个大家有没有想到 就是一个螺旋形状&#xff0c;那这道题我们应该怎么解决&#xff1f; 我们先来仔细的看&#xff0c;它这种螺旋形状的遍历是先【右-下-左-上】…

Docker中Tomcat部署步骤

第一次访问没有东西。

为什么我不推荐任何人用C语言作为编程启蒙第一课?

前言 写了20多年的代码&#xff0c;之前做过阿里的高级架构师&#xff0c;在技术这条路上跌跌撞撞了很多&#xff0c;我今天分享一些我个人的自学方法给各位。为什么我会说&#xff1a;不推荐任何人用C语言作为编程启蒙第一课&#xff1f; 这里有很多同学要站出来说了&#x…

实现CP指令

一、文件的打开创建 #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags); flags: O_RDONLY 只读 O_WRONLY 只写 O_RDWR 可读可写 int open(const char *pathname, int flags, mode_t mode); 如果 …

VsCode美化 - VsCode自定义 - VsCode自定义背景图

VsCode美化 - VsCode自定义 - VsCode自定义背景图&#xff1a;添加二次元老婆图到VsCode 前言 作为一个二刺螈&#xff0c;VsCode用久了&#xff0c;总觉得少了些什么。是啊&#xff0c;高效的代码生产工具中怎么能没有老婆呢&#xff1f; 那就安装一个VsCode插件把老婆添加…

章节7:Burp Intruder模块

章节7&#xff1a;Burp Intruder模块 参考资料 https://portswigger.net/burp/documentation/desktop/tools/intruder 01 Intruder模块作用与原理 原理 http://xxx.xx.com/bbs/index.php?namewuyanzu&mottogo 对请求参数进行修改&#xff0c;分析响应内容&#xff0…

Linux 内核第一版 (v0.01) 开源代码解读

探索Linux v0.01的内部结构&#xff0c;Linux内核经常被认为是一个庞大的开源软件。在撰写本文时&#xff0c;最新版本是v6.5-rc5&#xff0c;包含36M行代码。不用说&#xff0c;Linux是几十年来许多贡献者辛勤工作的成果。 Linux 内核首个开源版本 (v0.01) 的体积非常小&…

四、Dubbo扩展点加载机制

四、Dubbo扩展点加载机制 4.1 加载机制概述 Dubbo良好的扩展性与框架中针对不同场景使用合适设计模式、加载机制密不可分 Dubbo几乎所有功能组件都是基于扩展机制&#xff08;SPI&#xff09;实现的 Dubbo SPI 没有直接使用 Java SPI&#xff0c;在它思想上进行改进&#xff…

竞赛项目 深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …