iview权限管理怎么实现,分配权限操作是怎样
Admin 2022-05-24 群英技术资讯 545 次浏览
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指令,或者自定义一个鉴权组件用来包裹需要鉴权的元素。
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.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) }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要为大家详细介绍了Vue组件库ElementUI实现表格列表分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本篇文章带大家了解一下Angular中的变更检测,先从一个小的示例入手,然后逐步展开深入聊聊变更检测,希望对大家有所帮助!
文章中涉及 ref 的应用仅为父组件调用子组件场景下的应用方式,并未涵盖 ref 的所有应用方式!
怎样用js实现图片隐藏和显示效果?图片的隐藏和显示效果我们经常能在网站上看到,这个功能也是比较实用的,很多朋友想要知道如何用JavaScript来实现图片隐藏和显示,下面小编就给大家分享一些js实现图片隐藏和显示的代码供大家参考。
前言用Vue3实现一个简易的音乐播放器组件其效果图如下所示:实现这个组件需要提前做的准备:引入ElementUI引入字节跳动图标库一张唱见图片将要播放的音乐上传到文件服务器上,并提供一个能在线访问的链接【这里使用的是阿里云的OSS服务】准备ElementUIElementUI的引入可以参照其官网的引入方式;字节跳动图标
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008