博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue2.0 + ElementUI 手写权限管理系统后台模板(二)——权限管理
阅读量:6265 次
发布时间:2019-06-22

本文共 7386 字,大约阅读时间需要 24 分钟。

权限验证

页面级别权限

路由:

默认挂载不需要权限的路由,例如:登录、主页。需要权限的页面通过 (点击查看官方文档) 动态添加更多的路由规则,404拦截页面需要放在路由表的最后,否则 /404 后面的路由会被404拦截,通过(点击查看官方文档)记录路由需要的权限。为了菜单列表可以被翻译,路由表的 name 属性值通过 i18n 的英文对照表来获取,也可以直接写英文名称,如 name: routeNmae.builtInIcon 可以直接写成 name: "builtInIcon",凭个人喜好

// src/router/index.jsimport en from '../i18n/lang/en' // 路由名字 name import Vue from 'vue'import Router from 'vue-router'import CommerViews from '@/views/commerViews'import Login from '@/views/login/index'import Layout from '@/views/layout/layout'import HomeMain from '@/views/index/mainIndex'// 不是必须加载的组件使用懒加载const Icon = () => import('@/views/icon/index')const Upload = () => import('@/views/upload/upload')const Markdown = () => import('@/views/markdown/markdownView')const NotFound = () => import('@/page404')Vue.use(Router)let routeNmae = en.routeNmae// 不需要权限的路由let defaultRouter = [  { path: '/',    redirect: '/index',    hidden: true,    children: []  },  {    path: '/login',    component: Login,    name: '',    hidden: true,    children: []  },  {    path: '/index',    iconCls: 'fa fa-dashboard', // 菜单图标,直接填写字体图标的 class    name: routeNmae.home,    component: Layout,    alone: true,    children: [      {        path: '/index',        iconCls: 'fa fa-dashboard',        name: '主页',        component: HomeMain,        children: []      }    ]  },  {    path: '/404',    component: NotFound,    name: '404',    hidden: true,    children: []  },]// 需要 addRouters 动态加载的路由 let addRouter = [  {    path: '/',    iconCls: 'fa fa-server',    name: routeNmae.multiDirectory,    component: Layout,    children: [      {        path: '/erji1',        iconCls: 'fa fa-server',        name: routeNmae['menu2-1'],        component: Erji,        children: []      },      {        path: '/erji3',        iconCls: 'fa fa-server',        name: routeNmae['menu2-3'],        component: CommerViews, // 无限极菜单的容器 超过三级菜单父级容器需要使用 CommerViews        children: [          {            path: '/sanji2',            iconCls: 'fa fa-server',            name: routeNmae['menu3-2'],            component: Sanji2,            children: []          },          {            path: '/sanji3',            iconCls: 'fa fa-server',            name: routeNmae['menu3-3'],            component: CommerViews,            children: [              {                path: '/siji',                iconCls: 'fa fa-server',                name: routeNmae['menu4-1'],                component: Siji,                children: []              },              {                path: '/siji1',                iconCls: 'fa fa-server',                name: routeNmae['menu4-2'],                component: CommerViews,                children: [                  {                    path: '/wuji',                    iconCls: 'fa fa-server',                    name: routeNmae['menu5-1'],                    component: Wuji,                    children: []                  }                ]              }            ]          }        ]      }    ]  },    {    path: '/',    iconCls: 'el-icon-edit', // 图标样式class    name: routeNmae.editor,    component: Layout,    meta: {role: ['superAdmin', 'admin']}, // 需要权限 'superAdmin', 'admin'。meta属性可以放在父级,验证父级和所有子菜单,也可以放在子级单独验证某一个子菜单    children: [      {        path: '/markdown',        iconCls: 'fa fa-file-code-o', // 图标样式class        name: routeNmae.markdown,        component: Markdown,        children: []      }    ]  },  { path: '*',    redirect: '/404',    hidden: true,    children: []  },]export default new Router({  routes: defaultRouter})export {defaultRouter, addRouter}

然后通过 token 获取当前登录用户的个人信息,在router被挂载到Vue之前和需要权限的路由表做对比,筛选出当前角色的动态路由表,

// main.js//  获取角色信息,根据用户权限动态加载路由router.beforeEach((to, from, next) => {  if (store.getters.token) { // 查看 token 是否存在    store.dispatch('setToken', store.getters.token) // 每次操作都重新写入 token,延长有效会话时间    if (to.path === '/login') {      next({path: '/'})    } else {      if (!store.getters.info.role) { // 查看是否有当前用户角色,如果没有则获取角色信息        !async function getAddRouters () {          await store.dispatch('getInfo', store.getters.token) // 通过token获取角色信息          await store.dispatch('newRoutes', store.getters.info.role) // 通过权限筛选新路由表          await router.addRoutes(store.getters.addRouters) // 动态加载新路由表          next({path: '/index'})        }()      } else {        let is404 = to.matched.some(record => { // 404页面拦截          if(record.meta.role){          // 没有权限的页面,跳转的404页面            return record.meta.role.indexOf(store.getters.info.role) === -1          }        })        if(is404){          next({path: '/404'})          return false        }        next()      }    }  } else {    if (to.path === '/login') {      next()    }    next({path: '/login'})  }})

actions: getInfo

// src/vuex/modules/role.jsstate: {    info: '' // 每次刷新都要通过token请求个人信息来筛选动态路由  },  mutations: {    getInfo (state, token) {      // 省略 axios 请求代码 通过 token 向后台请求用户权限等信息,这里用假数据赋值      state.info = {        role: 'superAdmin',        permissions: '超级管理员'      }      // 将 info 存储在 sessionStorage里, 按钮指令权限将会用到      sessionStorage.setItem('info', JSON.stringify(store.getters.info))    },    setRole (state, options) {  // 切换角色,测试权限管理      state.info = {        role: options.role,        permissions: options.permissions      }      sessionStorage.setItem('info', JSON.stringify(store.getters.info));      // 权限切换后要根据新权限重新获取新路由,再走一遍流程      store.dispatch('newRoutes', options.role)      router.addRoutes(store.getters.addRouters)    }  },  actions: {    getInfo ({commit}, token) {      commit('getInfo', token)    },    setRole ({commit}, options){// 切换角色,测试权限管理,不需要可以删除      commit('setRole', options)    }  }

actions: newRoutes

// src/vuex/modules/routerData.jsimport {defaultRouter, addRouter} from '@/router/index'const routerData = {state: {    routers: [],    addRouters: []  },  mutations: {    setRouters: (state, routers) => {      state.addRouters = routers  // 保存动态路由用来addRouter      state.routers = defaultRouter.concat(routers) // 所有有权限的路由表,用来生成菜单列表    }  },  actions: {    newRoutes ({commit}, role) {      //  通过递归路由表,删除掉没有权限的路由      function eachSelect (routers, userRole) {        for (let j = 0; j < routers.length; j++) {          if (routers[j].meta && routers[j].meta.role.length && routers[j].meta.role.indexOf(userRole) === -1) {          // 如果没有权限就删除该路由,如果是父级路由没权限,所有子菜单就更没权限了,所以一并删除            routers.splice(j, 1)            j = j !== 0 ? j - 1 : j // 删除掉没有权限的路由后,下标应该停止 +1,保持不变,如果下标是 0的话删除之后依然等于0          }          if (routers[j].children && routers[j].children.length) {           //  如果包含子元素就递归执行            eachSelect(routers[j].children, userRole)          }        }      }      // 拷贝这个数组是因为做权限测试的时候可以从低级切回到高级角色,仅限演示,正式开发时省略这步直接使用 addRouter      // 仅限演示      let newArr = [...addRouter]      eachSelect(newArr, role)      commit('setRouters', newArr)      // 正式开发      // eachSelect(addRouter, role)      // commit('setRouters', addRouter)    }  }}export default routerData

按钮级别权限验证

通过自定义指令获取当前按钮所需的有哪些权限,然后和当前用户的权限对比,如果没有权限则删除按钮

// btnPermission.jsimport Vue from 'vue'Vue.directive('roleBtn',{  bind:function (el,binding) {    let roleArr = binding.value; // 获取按钮所需权限    let userRole =  JSON.parse(sessionStorage.getItem('info')).role // 获取当前用户权限    if (roleArr && roleArr.indexOf(userRole) !== -1) {      return false    } else {      el.parentNode.removeChild(el);    }  }})export default Vue

使用自定义指令权限

查看
添加
删除
修改

转载地址:http://nkcpa.baihongyu.com/

你可能感兴趣的文章
统计、案例-深入理解Oracle索引(10):索引列字符类型统计信息的32位限制-by小雨...
查看>>
ubuntu常用命令精选
查看>>
UML类图
查看>>
企业上市上市央企大面积亏损折射出啥弊端?
查看>>
DXP_protel2004_原理图设计基础_集成运放原理图设计学习
查看>>
powershell--uninstall webapplication
查看>>
ubuntu配置vsftpd记录
查看>>
日期控件Android 自定义日历控件
查看>>
Java多线程编程:变量共享分析(Thread)
查看>>
word如何自动生成目录
查看>>
疯狂暑期学习计划~~~
查看>>
Mysql查询大表出现的一个错误
查看>>
Scala 中的foreach和map方法比较
查看>>
使用OWIN作为WebAPI的宿主
查看>>
阿里巴巴、腾讯、百度的面试问题笔知识汇总(两)
查看>>
如果他们在未来的几年内技术水平没有突破性的提升,或者缺乏一点灵性和品味,那么可能在未来很长一段时间内,他们都会保持这个薪资水平(转)...
查看>>
修改setup.py的源
查看>>
SQL Server 常用高级语法笔记
查看>>
IOS开发之SVN的使用
查看>>
百度.搜狐...2015产品经理面试题
查看>>