您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

iview 权限管理的实现

51自学网 2022-05-02 21:36:27
  javascript

iview-admin2.0自带的权限管理

iview-admin2.0自带权限管理,可以通过设置路由的meta对象的参数access来分配权限。
默认的角色是super_admin和admin,现在我们给文档这个侧边栏项目分配一个只有user才能查看的权限

  {    path: '',    name: 'doc',    meta: {      title: '文档',      href: 'https://lison16.github.io/iview-admin-doc/#/',      icon: 'ios-book',      access: ['user']    }  },

侧边栏就不会显示文档这个栏目了。在src/store/module/app.js中获取menuList,这个就是侧边栏的list

  getters: {    menuList: (state, getters, rootState) => getMenuByRouter(routers, rootState.user.access),    errorCount: state => state.errorList.length  },

这个getter方法主要是执行了getMenuByRouter,接着查看src/libs/util.js找到具体代码

/** * @param {Array} list 通过路由列表得到菜单列表 * @returns {Array} */export const getMenuByRouter = (list, access) => {  let res = []  forEach(list, item => {    if (!item.meta || (item.meta && !item.meta.hideInMenu)) {      let obj = {        icon: (item.meta && item.meta.icon) || '',        name: item.name,        meta: item.meta      }      if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, access)) {        obj.children = getMenuByRouter(item.children, access)      }      if (item.meta && item.meta.href) obj.href = item.meta.href      if (showThisMenuEle(item, access)) res.push(obj)    }  })  return res}
const showThisMenuEle = (item, access) => {  if (item.meta && item.meta.access && item.meta.access.length) {    if (hasOneOf(item.meta.access, access)) return true    else return false  } else return true}

到这里,access判断权限的过程就比较明白了。代码会获取state里存放的用户信息,主要是access,然后和路由允许的access进行比对,如果用户的access在路由access列表允许的范围内就确权,例如用户access的['admin','super_admin'],但是我们把文档的access设置为['user'],

hasOneOf(['admin','super_admin'],['user']) // false,鉴权失败

hasOneOf是iview-admin的工具方法。用于判断要查询的数组是否至少有一个元素包含在目标数组中,详细代码放在底部。

根据权限控制组件展示

一般我们还需要根据权限去控制页面元素的展示,比如按钮。有两种方法,一种是自定义auth指令,或者自定义一个鉴权组件用来包裹需要鉴权的元素。

自定义auth指令

iview-admin把自定义指令统一放在src/directive文件夹下,directives.js文件负责引入单独定义在各个文件的自定义指令,统一导出。我们实现一个auth指令:

import draggable from './module/draggable'import clipboard from './module/clipboard'import auth from './module/auth'const directives = {  draggable,  clipboard,  auth}export default directives

然后在src/directive/index.js中导出了一个importDirective方法,入参是Vue,逻辑是注册指令。

import directive from './directives'const importDirective = Vue => {  /**   * 拖拽指令 v-draggable="options"   * options = {   *  trigger: /这里传入作为拖拽触发器的CSS选择器/,   *  body:    /这里传入需要移动容器的CSS选择器/,   *  recover: /拖动结束之后是否恢复到原来的位置/   * }   */  Vue.directive('draggable', directive.draggable)  /**   * clipboard指令 v-draggable="options"   * options = {   *  value:    /在输入框中使用v-model绑定的值/,   *  success:  /复制成功后的回调/,   *  error:    /复制失败后的回调/   * }   */  Vue.directive('clipboard', directive.clipboard)  Vue.directive('auth', directive.auth) }export default importDirective

这个importDirective方法在main.js里面被用到了,并且把真实的Vue传入做为入参。

import importDirective from '@/directive'/** * 注册指令 */importDirective(Vue)...

编辑src/directive/module/auth.js

import store from '@/store'export default {  inserted: (el, binding, vnode) => {    const value = binding.value    const access = store.state.user.access    if (access.indexOf(value) === -1) {      el.remove()    }  }}

我们新增一个auth指令,并导出。在注入的时候进行权限判断,如果确权成功就不做什么,如果失败就把元素删除。
使用试试,拿顶部的折叠菜单按钮做例子,beader-bar.vue

<template>  <div class="header-bar">    <sider-trigger v-auth="'admin'" :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>    ...  </div></template>

当v-auth="'admin'"的时候显示按钮,如果是user则会隐藏按钮。

自定义auth组件

也可以通过自定义auth组件的方式来实现,创建一个函数式组件auth.vue

<script>import store from '@/store'export default {  functional: true,  props: {    authority: {      type: String,      require: true    }  },  render (h, context) {    const { props, scopedSlots } = context    const access = store.state.user.access    return access.indexOf(props.authority) > -1 ? scopedSlots.default() : null  }}</script>

如果确权成功就返回slot,否则返回null,这样被auth包裹的元素就不会展现了。然后把auth.vue注册为全局组件,免得每次使用都要import一下。编辑main.js

import Auth from '_c/auth/auth.vue'// 注册组件Vue.component('Auth',Auth)

使用的时候直接用auth包裹组件即可

<template>  <div class="header-bar">    <Auth authority="user">      <sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>    </Auth>  </div></template>

总结

不论是用组件式的写法还是自定义指令都能实现,组件的方式实现要写的代码多一点,用自定义指令比较灵活,此外有一点不同,自定义指令如果确权失败,是把元素直接删除掉了,所以此时如果再由admin改为user,元素还是不会展示的,因为已经被删除了嘛,需要刷新一下页面才能显示出来,但是如果是组件式的就不会,能够灵活响应。这个一般影响不大。

注意到我把access设置为了一个String,如果设置为一个数组也可以,iview自带的hasOneOf方法可以很好的使用

/** * @param {Array} target 目标数组 * @param {Array} arr 需要查询的数组 * @description 判断要查询的数组是否至少有一个元素包含在目标数组中 */export const hasOneOf = (targetarr, arr) => {  return targetarr.some(_ => arr.indexOf(_) > -1)}

到此这篇关于iview 权限管理的实现的文章就介绍到这了,更多相关iview 权限管理内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


关于var在for循环遇到的问题解决
浅谈JavaScript中的parseInt()的妙用
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1