vue3-实战-15-管理后台-动态实现菜单权限和按钮权限

news2024/9/23 13:27:23

目录

1-菜单路由权限分析

2-菜单权限实现

2.1-路由拆分

2.2-动态计算当前用户的权限

3-按钮权限实现


1-菜单路由权限分析

       目前我们系统中有:login(登录页面)、404(404一级路由)、任意路由、首页(/home)、数据大屏、权限管理(三个子路由)商品管理模块(四个子路由)。我们现在需要实现不同角色有不同的权限,所以我们需要对路由进行拆分。

静态(常量)路由:大家都可以拥有的路由。比如我们的 login、首页、数据大屏、404;
异步路由:不同的身份有的有这个路由、对于我们系统就是权限管理(三个子路由)商品管理模块(四个子路由)。
任意路由:就是除了上面两个路由之外的路由,我们定义重定向404。

2-菜单权限实现

2.1-路由拆分

我们按照上面的逻辑将路由进行拆分。文件src\router\router.ts拆分后如下:

//对外暴露配置路由(常量路由):全部用户都可以访问到的路由
export const constantRoute = [
  {
    //登录
    path: '/login',
    component: () => import('@/views/login/index.vue'),
    name: 'login',
    meta: {
      title: '登录', //菜单标题
      hidden: true, //代表路由标题在菜单中是否隐藏  true:隐藏 false:不隐藏
      icon: 'Promotion', //菜单文字左侧的图标,支持element-plus全部图标
    },
  },
  {
    //登录成功以后展示数据的路由
    path: '/',
    component: () => import('@/layout/index.vue'),
    name: 'layout',
    meta: {
      title: '',
      hidden: false,
      icon: '',
    },
    redirect: '/home',
    children: [
      {
        path: '/home',
        component: () => import('@/views/home/index.vue'),
        meta: {
          title: '首页',
          hidden: false,
          icon: 'HomeFilled',
        },
      },
    ],
  },
  {
    //404
    path: '/404',
    component: () => import('@/views/404/index.vue'),
    name: '404',
    meta: {
      title: '404',
      hidden: true,
      icon: 'DocumentDelete',
    },
  },
  {
    path: '/screen',
    component: () => import('@/views/screen/index.vue'),
    name: 'Screen',
    meta: {
      hidden: false,
      title: '数据大屏',
      icon: 'Platform',
    },
  },
]

//异步路由
export const asnycRoute = [
  {
    path: '/acl',
    component: () => import('@/layout/index.vue'),
    name: 'Acl',
    meta: {
      title: '权限管理',
      icon: 'Lock',
    },
    redirect: '/acl/user',
    children: [
      {
        path: '/acl/user',
        component: () => import('@/views/acl/user/index.vue'),
        name: 'User',
        meta: {
          title: '用户管理',
          icon: 'User',
        },
      },
      {
        path: '/acl/role',
        component: () => import('@/views/acl/role/index.vue'),
        name: 'Role',
        meta: {
          title: '角色管理',
          icon: 'UserFilled',
        },
      },
      {
        path: '/acl/permission',
        component: () => import('@/views/acl/permission/index.vue'),
        name: 'Permission',
        meta: {
          title: '菜单管理',
          icon: 'Monitor',
        },
      },
    ],
  },
  {
    path: '/product',
    component: () => import('@/layout/index.vue'),
    name: 'Product',
    meta: {
      title: '商品管理',
      icon: 'Goods',
    },
    redirect: '/product/trademark',
    children: [
      {
        path: '/product/trademark',
        component: () => import('@/views/product/trademark/index.vue'),
        name: 'Trademark',
        meta: {
          title: '品牌管理',
          icon: 'ShoppingCartFull',
        },
      },
      {
        path: '/product/attr',
        component: () => import('@/views/product/attr/index.vue'),
        name: 'Attr',
        meta: {
          title: '属性管理',
          icon: 'ChromeFilled',
        },
      },
      {
        path: '/product/spu',
        component: () => import('@/views/product/spu/index.vue'),
        name: 'Spu',
        meta: {
          title: 'SPU管理',
          icon: 'Calendar',
        },
      },
      {
        path: '/product/sku',
        component: () => import('@/views/product/sku/index.vue'),
        name: 'Sku',
        meta: {
          title: 'SKU管理',
          icon: 'Orange',
        },
      },
    ],
  },
]

//任意路由
export const anyRoute = {
  //任意路由
  path: '/:pathMatch(.*)*',
  redirect: '/404',
  name: 'Any',
  meta: {
    title: '任意路由',
    hidden: true,
    icon: 'DataLine',
  },
}

2.2-动态计算当前用户的权限

       当我们登录账号后,我们获取用户信息接口会返回当前用户拥有的菜单和按钮权限,我们需要对服务端返回的菜单和按钮权限进行处理,得到当前用户的菜单和按钮权限数据。
ps:
1:每次我们计算异步路由的时候,我们需要对router配置的异步路由进行一次深度拷贝;
2:当我们直接访问异步路由的时候,刷新,页面出现空白,我们发现页面的dom没有加载完成,我们需要在守卫那边,等待加载完成,再渲染页面。

 

//用于过滤当前用户需要展示的异步路由
function filterAsyncRoute(asnycRoute: any, routes: any) {
  return asnycRoute.filter((item: any) => {
    if (routes.includes(item.name)) {
      if (item.children && item.children.length > 0) {
        item.children = filterAsyncRoute(item.children, routes)
      }
      return true
    }
  })
}

3-按钮权限实现

       在获取用户信息接口,接口会返回当前用户拥有的按钮的权限,我们在用户仓库中存储当前用户的按钮权限。然后定义一个全局指令,在按钮的地方使用该指令,来控制按钮的显示和隐藏。

 

 指令文件src\directive\has.ts里面核心逻辑如下:

import pinia from '@/store'
import useUserStore from '@/store/modules/user'
const userStore = useUserStore(pinia)
export const isHasButton = (app: any) => {
  //获取对应的用户仓库
  //全局自定义指令:实现按钮的权限
  app.directive('has', {
    //代表使用这个全局自定义指令的DOM|组件挂载完毕的时候会执行一次
    mounted(el: any, options: any) {
      //自定义指令右侧的数值:如果在用户信息buttons数组当中没有
      //从DOM树上干掉
      if (!userStore.buttons.includes(options.value)) {
        el.parentNode.removeChild(el)
      }
    },
  })
}

       在入口文件main.ts中需要注册

 

       我们在项目中有按钮权限的地方直接使用该指令就可以显示当前按钮的隐藏和显示。比如我们在品牌管理模块的添加品牌v-has="`btn.Trademark.add`"中使用。

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

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

相关文章

libevent(14)bufferevent的client端例子

前面我们写了基于bufferevent的server端&#xff0c;这里我们写1个基于bufferevent的client端。 test_libevent_client.cpp&#xff1a; #include <string.h> #include <errno.h> #include <stdio.h> #include <signal.h> #include <netinet/in.h&…

wsl下面的子系统启用systemctl

下载地址 https://github.com/gdraheim/docker-systemctl-replacement 操作 mv /usr/bin/systemctl /usr/bin/systemctl.old #对原文件进行备份sudo scp /mnt/c/Users/Administrator/Desktop/systemctl.py /usr/bin/systemctl #把项目中的systemctl.py文件拷贝到/use/bin/ 目…

vitest测试 element-plus二次封装组件时css文件报错

bug描述&#xff1a;使用 element-plus 二次封装组件&#xff0c;使用 vitest 测试时报错&#xff0c;对于 element-plus 的 css 样式识别失败。 报错内容&#xff1a; Unknown file extension “.css” for D:\demo\omniButton\node_modules.pnpm\registry.npmmirror.comeleme…

SQL专家云快速解决阻塞

背景 当数据库突然产生严重阻塞时&#xff0c;运维人员要快速找到阻塞的源头并处理&#xff0c;让业务快速恢复。但是大多数运维人员只掌握了sp_who2、sp_lock等简单的语句&#xff0c;存在以下不足&#xff1a; 找不到真正的源头&#xff0c;过程中会误杀掉大量的会话&#xf…

IDE写代码,你用哪一款比较好?

目前市面上IDE种类非常多&#xff0c;很多程序员都会纠结究竟用哪一种IDE写代码比较好呢&#xff1f;IDE不过是写代码的辅助工具而已&#xff0c;运行环境和书写格式其实都一样&#xff0c;关键在于你用哪一款比较顺手。以下为大家推荐一些&#xff0c;一些常用的IDE工具&#…

助推人脉从资源化变成资产化,开利网络持续赋能广东商合会数字化

在企业经营发展的过程中&#xff0c;资源尤其是人脉资源的积累和应用是企业一直要做的事情&#xff0c;能够帮助企业建立强大的关系网络、从中也可能诞生更多的商机。开利网络服务客户商合会科技发展&#xff08;广东&#xff09;有限公司正是基于人脉资源的对接与增值而研发了…

【疑难解决】EasyCVR激活授权不成功的原因排查与解决

我们的EasyCVR等视频平台授权方式有这几种&#xff1a;加密机、加密狗、激活码&#xff0c;关于授权相关的问题&#xff0c;我们在此前的文章中也分享了很多&#xff0c;有需要的用户可以翻阅往期的文章进行了解。 有用户反馈&#xff0c;上传激活码文件后&#xff0c;既无报错…

STM32单片机(九)USART串口----第八节:FlyMcu串口下载

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

OSI参考模型(四)

目录 OSI模型 一、物理层 二、数据链路层 三、网络层 四、传输层 五、会话层 六、表示层 七、应用层 OSI模型 OSI七层模型&#xff0c;是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)1984年联合制定的开放系统互联参考模型&#xff0c;为开放式互联信息系统提供…

基于QQ邮箱实现验证码

基于QQ邮箱实现验证码 qq邮箱市场占有率挺高的。而且邮箱获取验证码也是比较方便的。 而且qq邮箱验证码是不收费的对于小白和初级开发者是比较友好的&#xff0c;而且是比较好上手的。 1.开发 1.进入qq邮箱点击设置。 2.点击账户 3.找到如下 没开启的需要开启一下&#xff0…

使用Cursor自动编写一个图像查看工具

imageview 最近忙于项目,断更许久,随便写点东西吧。今天跟大家分享的,是基于cursor 自动生成和稍加润色的一个图片显示工具。最近在做半导体AOI软件,其中有一个模块需要在相机实时取像时,显示图像,图像要能支持缩放、移动和中心标定。总的来说,实现的功能也比较简单。使…

如何避免死锁——方法2_ubique_lock

前文&#xff1a;如何避免死锁&#xff1a;方法一_御坂美琴1的博客-CSDN博客 unique_lock<mutex> 大部分情况下可以和lock_guard<mutex>替换。但是前者更灵活&#xff0c;同时也占用了更多的内存资源。 unique_lock也是一个模板类。 unique_lock<mutex> gua…

vue?parseHTML?函数源码解析

目录 正文函数开头定义的一些常量和变量while 循环 textEnd 0parseStartTag 函数解析开始标签 总结&#xff1a; 正文 接上篇&#xff1a; Vue编译器源码分析AST 抽象语法树 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 …

【遇到的问题】ServiceLoader.load(Driver.class),没有找到Driver接口对应的实体类

ServiceLoader ServiceLoder的SPIServiceLoader.load(Driver.class)的作用 代码详解出现的问题解决方式 ServiceLoder的SPI ServiceLoader.load(Driver.class)的作用 java.util.ServiceLoader工具类方法会使用ClassLoad类的getResources方法获取指定目录下的文件&#xff0c;…

C语言中的字符串输入(gets_s、fgets、scanf、fscanf)与相关内存分配知识

0. C语言的内存分配知识 分配内存空间有两种方式&#xff1a;静态内存分配和动态内存分配 0.1 静态内存分配 指的是在编译时确定数组等数据类型的大小&#xff0c;然后由计算机分配好&#xff0c;通常是存在栈上的数据 例如&#xff1a;在声明数组时&#xff0c;需要显示的指明…

Nacos 配置统一管理、热部署、多环境配置共享

目录 一、Nacos 配置统一管理 1.1、启动 Nacos 服务 1.2、Nacos 新建配置 1.3、引入依赖 1.4、Nacos 地址读取 1.5、演示效果 二、Nacos 配置热部署 三、多环境配置共享 一、Nacos 配置统一管理 1.1、启动 Nacos 服务 在当前文件下打开终端&#xff0c;输入如下指令启…

vue2实现卡片拖拽式课程表

目录 一、效果展示 二、代码分析 2.1、两栏布局、表格编写与课程卡片 2.2、初始化数据与渲染 2.3、拖拽卡片到表格&#xff0c;进行插入 2.4、自定义指令进行删除 一、效果展示 二、代码分析 主页面代码&#xff1a; <template><div class"board"&…

【QT】枚举常用宏(Q_ENUM,Q_FLAG,Q_DECLARE_FLAGS,Q_DECLARE_OPERATORS_FOR_FLAGS)

目录 1. Q_ENUM宏 与 QMetaEnum类1.1 Q_ENUM宏的作用1.2 使用Q_ENUM注意的问题1.3 在写有关枚举的代码时&#xff0c;我们可能遇到这种情况&#xff1a;需要用到枚举的字符串&#xff0c;该怎么办&#xff1f;1.4 下面通过一段简单的代码来说明Q_ENUM的作用 2. Q_FLAG宏2.1 Q_F…

datax mysql同步数据到clickhouse配置文件样例及说明

datax mysql同步数据到clickhouse配置文件样例及说明 { "job": { "content": [ { "reader": { "parameter": { "password": "…

魔兽世界私人服务器怎么开

开设魔兽世界的私人服务器涉及到一系列复杂的步骤和技术要求。下面是一个大致的指南&#xff0c;以供参考&#xff1a; 1. 硬件需求&#xff1a;首先&#xff0c;你需要一台强大的服务器来承载游戏服务器。服务器的规模和配置将取决于你计划同时容纳多少玩家以及服务器的性能要…