vue 后台系统权限管理

前言

最近在做一个后台管理系统,一般的后台系统都有权限管理这块,下面我就分享下我实现权限管理这块的思路。

技术栈及实现思路

首先说下这个系统前端用到的技术栈,vue全家桶,element-ui,axios。首先,用户的权限是通过前端来进行配置的,那么就需要一个页面去进行用户的权限配置。在用户登录之后,通过请求后台查找该用户的权限信息,然后返回到前端。前端拿到权限信息之后,动态配置路由,再生成出对应的菜单列表。

如何进行权限配置

权限分配页面

毋庸置疑,权限是跟用户挂钩的。在用户管理页面,做一个授权页面。如下图:
vue 后台系统权限管理_第1张图片
树结构用的是element-ui里面的树形控件。生成这个树形菜单的数据源为前端配置好的默认的路由表。'icon’为菜单对应的图表,'index’为自定义的索引,用来配合这个树形控件生成权限信息。

export const homeRoute = {
  path: '/',
  component: index,
  redirect: '/home',
  children: []
};
export const routes = [
  {
    path: '/home',
    component: home,
    icon: 'el-icon-home',
    index: '1',
    name: '系统首页',
    disabled: true
  }, {
    path: '/list',
    component: list,
    icon: 'el-icon-tickets',
    name: '菜单1',
    redirect: '/list1',
    index: '2',
    children: [
      {
        path: '/list1',
        name: '菜单列表1',
        component: list1,
        index: '2-1'
      },
      {
        path: '/list2',
        name: '菜单列表2',
        component: list2,
        index: '2-2'
      }
    ]
  }, {
    path: '/userManage',
    component: userManage,
    icon: 'el-icon-ticket',
    name: '用户管理',
    index: '3'
  }
];

首页默认是所有用户都能查看的。当为改用户勾选对应的菜单后,则会生成一个数组,存储着选中的菜单列表,如:[‘1’, ‘2-1’, ‘3’, ‘2’, ‘2-2’]。

动态配置路由

我在main.js文件做了如下配置:

var per = true;
router.beforeEach((to, from, next) => {
  if (getStore('token') == null && to.path !== '/login') {
    next('/login');
  } else {
    if (from.path !== '/login') {
      if (per) {
        store.dispatch('setPermList').then(() => {
          per = false;
        });
      } else {
        next();
      }
    } else {
      next();
    }
  }
  next();
});

当页面每次刷新的时候(ps:定义per变量,就是为了防止每次进刷新的时候去dispatch,而是在页面刷新的时候去触发),去dispatch.状态管理的代码如下。首先拿到用户权限数组,然后分成一级菜单跟二级菜单两个数组。对一级菜单和默认的路由表进行遍历,筛选出有权限的路由表,再过滤掉一级路由里没有权限的二级路由。

const state = {
  permList: []
};
const getters = {
  permList: state => state.permList
};
const getters = {
  permList: state => state.permList
};
const actions = {
  setPermList ({commit}) {
    return new Promise(resolve => {
      api.getUserPerm().then(res => {
        let perm = res.data;
        // 一级菜单
        let oldParent = perm.filter(item => item.indexOf('-') < 0);
        // 一级菜单下的二级菜单
        let child = perm.filter(item => item.indexOf('-') > 0);
        // for (let c of child) {
        //   oldParent.push(c.split('-')[0]);
        // }
        child.map(c => {
          oldParent.push(c.split('-')[0]);
        });
        console.log(child);
        let newParent = [...new Set(oldParent)]; // 去重
        let routesList = [...new Set(routes)]; // 去重
        let parentArray = [];
        // 生成一级菜单
        newParent.map(
          item => {
            routesList.map(
              routesItem => {
                if (routesItem.index === item) {
                  let it = Object.assign({}, routesItem);
                  parentArray.push(it);
                }
              }
            );
          }
        );
        // 过滤掉一级菜单下的二级菜单
        for (let pItem of parentArray) {
          pItem.children = pItem.children ? pItem.children.filter(n => child.indexOf(n.index) != -1) : null;
        }
        homeRoute.children = parentArray;
        router.addRoutes([homeRoute]);
        commit(types.PERM_LIST, parentArray);
        resolve(perm);
      });
    });
  }
};
const mutations = {
  [types.PERM_LIST] (state, data) {
    state.permList = data;
  }
};

例如,当获取到的用户权限为:[‘1’, ‘2-1’, ‘3’],那么生成的路由为:

  {
    path: '/home',
    component: home,
    icon: 'el-icon-home',
    index: '1',
    name: '系统首页',
    disabled: true
  }, {
    path: '/list',
    component: list,
    icon: 'el-icon-tickets',
    name: '菜单1',
    redirect: '/list1',
    index: '2',
    children: [
      {
        path: '/list1',
        name: '菜单列表1',
        component: list1,
        index: '2-1'
      }
    ]
  }, {
    path: '/userManage',
    component: userManage,
    icon: 'el-icon-ticket',
    name: '用户管理',
    index: '3'
  }

根据路由生成首页菜单

路由数组都出来了,那么生成菜单就不在话下了。菜单也是用到了element-ui的菜单

  

生成的菜单如下:

vue 后台系统权限管理_第2张图片

补充

我在网上查阅到的后台权限管理,都是跟角色挂钩的,无法满足我的需求,于是在反复思考下想到了这样的做法,有些不足的地方还需要继续补充和完善。例如:目前在菜单级别上,只是做了一二级菜单,没有三级菜单。在状态管理生成新的路由的代码片段感觉写的有点繁琐,有待优化。希望大家能提出意见,想要看源码的可以私聊我。原文地址:https://juejin.im/post/5c08c3ece51d451dde1b0c08

你可能感兴趣的:(vue.js学习,JavaScirpt学习)