当前位置:首页 > 文章列表 > 数据库 > MySQL > vue权限管理系统

vue权限管理系统

来源:SegmentFault 2023-01-28 18:51:14 0浏览 收藏

编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《vue权限管理系统》,文章讲解的知识点主要包括MySQL、javascript、vue.js,如果你对数据库方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。

vue权限系统

后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口。大多数管理系统的页面都长这样。

下面预览图是我写的一个后台管理系统,源码请点击链接 vuets-iview-admin 技术栈 - vue+typescript+iview

image

左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮。

表的结构

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_auth_rule
-- ----------------------------
DROP TABLE IF EXISTS `t_auth_rule`;
CREATE TABLE `t_auth_rule` (
  `id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
  `auth_id` varchar(128) NOT NULL COMMENT '权限Id',
  `pauth_id` varchar(128) DEFAULT NULL COMMENT '父级Id',
  `auth_name` varchar(255) NOT NULL COMMENT '权限名称',
  `auth_icon` varchar(255) NOT NULL COMMENT '权限图标',
  `auth_type` smallint(6) NOT NULL COMMENT '权限类型,BIT表示其属性\r\n            0x00表示可显示的菜单权限节点;\r\n            0x01表示普通节点',
  `auth_condition` text COMMENT '条件',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `is_menu` smallint(255) DEFAULT '0' COMMENT '是否为菜单,0表示非,1表示是',
  `weight` int(11) NOT NULL DEFAULT '0' COMMENT '权重',
  `rule` varchar(256) DEFAULT NULL COMMENT '规则路径主要对应菜单或方法的路径名称',
  `cr_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `up_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id_pk`),
  UNIQUE KEY `AK_auth_id` (`auth_id`)
) ENGINE=InnoDB AUTO_INCREMENT=264 DEFAULT CHARSET=utf8 COMMENT='权限规则表,记录权限相关的信息,权限以父子关系存在,菜单是权限的一种。';

SET FOREIGN_KEY_CHECKS = 1;


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_role_auth
-- ----------------------------
DROP TABLE IF EXISTS `t_role_auth`;
CREATE TABLE `t_role_auth` (
  `id_pk` bigint(20) NOT NULL AUTO_INCREMENT,
  `role_id_fk` varchar(32) DEFAULT NULL COMMENT '角色id',
  `auth_id_fk` varchar(128) DEFAULT NULL COMMENT '权限id',
  `aa` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id_pk`)
) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8 COMMENT='角色与权限的关系表';

SET FOREIGN_KEY_CHECKS = 1;

稍微解释一下表结构,t_auth_rule 表用来存储对应的权限菜单,一般来说,菜单分为一级和二级菜单,rule字段对应前端的路由规则;而按钮为第三级,rule对应的是接口url地址。
t_role_auth 表为角色权限关联表,一个角色拥有哪些权限是通过这张表查出来的。当然还有一个role表,还有一个账号表,账号表里有一个role的外键。
这样就是一个账号 --> 角色 --> 权限的关系。

对于菜单的权限,通过路由表匹配

// 本地写好路由列表(需要进行动态匹配的)
export const routerList: Array = [
  // 首页
  {
    path: '/',
    name: '_home',
    redirect: '/home',
    component: Layout,
    meta: {
      hideInMenu: true,
      notCache: true
    },
    children: [
      {
        path: 'home',
        name: 'home',
        meta: {
          hideInMenu: true,
          title: '首页',
          notCache: true,
          icon: 'md-home'
        },
        component: () => import('@/views/overview-operations/data-center/DataCenter.vue')
      }
    ]
  }
]

// 负责将后台返回的 菜单列表 转成vue-router所需要的 router list
export function toRouterComponent(menuList: Array) {
  if (!menuList.length) return []

  let routerArr = [];
  for (let j = 0; j  i.path === menuList[j].url); // 一级菜单
    if (firstIndex !== -1) {
      let children: Array = []
      obj = {
        path: routerList[firstIndex].path,
        component: routerList[firstIndex].component,
        redirect: routerList[firstIndex].redirect,
        name: routerList[firstIndex].name,
        meta: routerList[firstIndex].meta,
        children
      };

      // 如果有子菜单
      if (menuList[j].children && menuList[j].children.length) {
        for (let k = 0; k  {
            let fullpath = '';
            if (routerList[firstIndex].path === '/') {
              fullpath = `${routerList[firstIndex].path}${i.path}`;
            } else {
              fullpath = `${routerList[firstIndex].path}/${i.path}`;
            }
            return fullpath === menuList[j].children[k].url;
          });
          if (secondIndex !== -1) {
            obj.children.push(_children[secondIndex]);
          }
        }
      }
    }

    if (obj) {
      routerArr.push(obj);
    }
  }

  return routerArr;
}

// 根据菜单权限,获取路由数组
// 本地只保存后台返回的菜单,在页面刷新的时候从本地拿到菜单重新调用toRouterComponent生成 路由数组
export function getRouterList() {
  if (!storage.get('username')) {
    storage.set('menuTree', ''); // 清空菜单权限数据
  }
  let menuList = storage.get('menuTree') ? storage.get('menuTree') : [];

  const routerArr = toRouterComponent(menuList);
  return routerArr;
}

menuList,菜单数组(或对象), 由后台返回; routerList为前端定义的路由表;遍历routerList,如果routerList的path在menuMap里能找到的话,就表示该路由存在。最后生成一个过滤后的路由表,用vue提供的addRoutes方法动态添加到路由中,并把过滤后的路由表存到本地。

在页面刷新的时候,从本地获取路由表,添加到路由表中,代码如下,constRouterArr为基础路由表,比如登录,404等

注意这一步有个问题,由于我写的storage库用了JSON.stringify,把路由表中的component(实际为一个函数)丢失了,所以在从本地获取路由的时候,还要重新生成一个新的路由表,重新把component加上去,即把上面的addrouters重新执行一遍

对于按钮的权限

if (res.data.auth_rule_map) {
    let obj = {}
    Object.keys(res.data.auth_rule_map).forEach(i => {
      // 将所有的按钮放到一个obj里 key 为接口地址  
      if (res.data.auth_rule_map[i].is_menu === 0) {  // 如果是按钮
        obj[res.data.auth_rule_map[i].rule] = 1
      }             
    })
    storage.set("btnList", obj);
    storage.set("menuTree", res.data.auth_rule_map);
}

auth_rule_map为接口返回权限map,把按钮的权限过滤出来存到本地
将map添加到每个路由组件的data里,(这里有一个问题,怎么判断一个组件是否是路由组件),目前想到的是通过组件name来判断,把所有的路由组件放到一个数组里做判断。

在组件内部的按钮上加上v-if,如果this.uri__里的uri在uriMap里存在就显示。
也可以通过方法来判断,如下面的__isBtnShow,不仅可以控制按钮的显示隐藏,还可以控制其样式,比如颜色等,更加灵活,推荐使用方法来控制

uri = {
    ADD_MEMBER: '/api/add_member'
}

export default function install (Vue) {
  const uriMap = storage.get('btnList')
  //uriMap['/admin/api/auth_rule/update_auth_rule.action'] = 1
  Vue.mixin({
    created() {
      const arr = ['MemberManage', 'PayManage', '...']
      if (arr.indexOf(this.$options.name) !== -1) {
        this.dataUri__ = uriMap
        this.uri__ = uri  
      }
    },
    data() {
      return {
        dataUri__: {}
      }
    },
    methods: {
      __isBtnShow(uri) {
        return uriMap[uri] ? 'display: inline-block' : 'display: none'
      },
    }
  })
}



// 通过方法来控制,更加灵活

登出的问题

**登出后要清空缓存,routerArr,btnList 等。
由于之前登录,调用addRouter把权限上个账号的路由表加进去了,所以登出后要location.reload()一次,重新实例化路由表,去掉动态添加的路由,只保留基础路由。
location.reload()体验不是太好,但是vue-router没有提供动态删除路由的api,比如 deleteRouter。**

同时登两个账号,导致刷新页面的时候,前者页面的本地缓存被覆盖,权限菜单等数据发生变化,路由表也发生变化

最简单的方法是存到localStorage里,只有登出才会清空缓存,只能登一个账号。

关于菜单和按钮的多语言放在前台还是后台

经过思考还是觉得放在前台好,有两点原因

  • 放在前台方便前台操作,切换语言时不需要重新从后台获取菜单和按钮的名称
  • 如果放在后台,新增语言的时候,后台还得加字段, 放在前台的话只需要更新一下语言包就行了

关于menutree 是否存到本地

之前一直是存在localstorage里,但是仔细一想还是有安全问题,用户可以通过api改变本地的menutree,刷新页面后还是会得到想要的权限,所以menutree 不能存到本地,只读到内存中,页面刷新后,再重新获取一次menutree,代价就是会牺牲一点用户体验。

关于左侧菜单栏重复push的问题

window.addEventListener('storage', () => {
  // 当同时打开两个网页 其中一个网页退出登录的时候 通知另一个网页刷新 把之前的路由清掉
  // 这样就不会重复push路由进去了
  if (getLsCache('username') === '') {
    window.location.reload();
    setTimeout(() => {
      this.$router.push('/login');
    }, 200);
  }
});
this.setLocal(this.$i18n.locale);

以上就是《vue权限管理系统》的详细内容,更多关于mysql的资料请关注golang学习网公众号!

版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
springboot+多线程简单实现springboot+多线程简单实现
上一篇
springboot+多线程简单实现
MySQL 给数据排序同时追加序号列
下一篇
MySQL 给数据排序同时追加序号列
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    14次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    22次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    40次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码