欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue权限管理系统的实现代码

程序员文章站 2023-11-18 22:12:46
后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口。大多数管理系统的页面都长这样。 左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮。...

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

vue权限管理系统的实现代码

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

表的结构

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;

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

addrouters(menumap) {
  let routerarr = [];
  for (let j = 0; j < routerlist.length; j++) {
    let obj;
    if (menumap['authrule::' + routerlist[j].path]) {   // 找到一级菜单
      obj = {
        path: routerlist[j].path,
        component: routerlist[j].component,
        redirect: routerlist[j].redirect,
        name: routerlist[j].name,
        meta: routerlist[j].meta,
        children: []
      };

      if (routerlist[j].children.length) {
        for (let k = 0; k < routerlist[j].children.length; k++) {
          let _fullpath = routerlist[j].children[k].path
          if (routerlist[j].children[k].meta) {
            _fullpath = routerlist[j].children[k].meta.parentpath + '/' + _fullpath 
          }
          if (menumap['authrule::' + _fullpath]) { // 找到二级菜单
            obj.children.push(routerlist[j].children[k]);
          }
        }
      }
    }
    if (obj) {
      routerarr.push(obj);
      this.$router.options.routes.push(obj);
    }
  }

  storage.set("routerarr", routerarr);
  this.$router.addroutes(routerarr);
  this.$router.push({ path: "/" });
},

menumap为登录时获取的权限菜单,是一个对象; routerlist为前端定义的路由表;遍历routerlist,如果routerlist的key在menumap里能找到的话,就表示该路由存在。最后生成一个过滤后的路由表,用vue提供的addroutes方法动态添加到路由中,并把过滤后的路由表存到本地。

const menumap = {
  '/dashboard': {path: '/dashboard', name: '首页'}
}
const routerlist = [
  {path: '/dashboard', name: '首页', component: ..}
]

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

const routerlist = storage.get('routerarr')
const routerarr = constrouterarr.concat(routerlist);

对于按钮的权限

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__: {}
   }
  },
 })
}

<button v-if="datauri__[uri__.add_member]">添加会员</button>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。