手机版

如何优雅地添加vue中的权限控制示例

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

前言

在项目中,一些功能将涉及重要的数据管理。为了保证数据安全,我们会给项目增加权限,限制每个用户的操作。作为前端,我们要做的就是配合后端给出的权限数据,对页面进行各种限制。

需求

因为这是工作中的业务需求,所以我主要有两个地方可以控制权限。

首先是侧面菜单栏,需要控制显示和隐藏。

第二个是页面中的按钮和弹出窗口。

过程

1.如何获得用户权限?

后端(当前用户拥有的权限列表)-前端(通过后端接口获取,以下我们称之为当前用户的权限列表)

2.如何限制前端?

根据产品需求配置项目中的权限点,然后通过permissionList了解是否有配置的权限点。如果有,就显示,如果没有,就不显示。

3.然后呢。

它不见了。

刚收到这个需求的时候也是这么想的。有什么难的?获取许可列表并进行判断。后来才发现,真正的需求远比我想象的复杂。

真正的问题

上面提到的需求,我们主要解决两个问题,即侧面菜单栏显示页面的操作。

假设我们有这样的路由设置(以下只是一个示例):

从' vue-router'/导入vue路由器*注意:以下配置只是部分配置,省略了组件配置*/导出const routes=[{path:'/',name:' admin ',Label:' home page'},{path:'/user ',name:' user ',label:' user ',Redirect : { name 3360 ' user list ' },children :[{ path 333660 label: '系统设置' },{path:'/login ',name:' login ',label : ' log in ' }]const router=new vue router({ routes })导出默认路由器,其中前两级路由将显示在侧边栏中,但第三级不会显示在侧边栏中。

在页面中设置操作权限不需要考虑很多其他的事情。我们主要分析侧边栏和路由问题。经分析,主要存在以下问题:

何时获取权限列表以及如何存储权限列表子路由在没有权限时不应显示(例如,当用户列表和用户组都没有权限时,用户不应显示在边栏中)。如果默认重定向路由没有权限,您应该在子路由中寻找具有权限的重定向(例如,用户路由被重定向到用户列表路由,如果用户列表没有权限,则应该被重定向到用户组路由。)当用户未经允许直接输入url时,需要未经允许跳转到页面或进行其他操作。(路由限制)以上问题我们会逐一解决。

何时获取权限,在哪里存储路由限制

我是从路由器中的beforeEach获取的,获得的permissionList存储在vuex中。

原因是考虑到路由的局限性和便于在以后的项目中使用权限列表,下面是一个实现示例:

首先,我们向路由器添加权限配置:

//下面只显示了一些配置{path:'/user ',name:' user ',label:' user ',meta : { permissions :[' u _ 1 ']},redirect : { name 3360 ' user list ' }。Children: [{path:' list ',name:' userlist ',label:' user list ',meta : { permissions :[' u _ 1 _ 1 ']},{path:' group ',Name:' user group ',label:' user group ',meta : { permissions :[' u _ 1 _ 2 ']},redirect : { name 3360 }为了更简单地判断来自router.beforeEch的权限,权限被设置为一个数组,因为一个页面可能涉及多个权限。

接下来,我们设置路由器。在每个:之前

//从项目的“@/store”引入vueximport store从“@/utils/permission”路由器引入import {includepermission}函数。beforeeach (async (to,from,next)={//首先判断是否是登录,然后登录后就可以获得权限。如何判断自己是否登录?IsLogin) {try {//这里获取权限列表awatstore . dispatch(' get permission list ')//这里判断当前页面是否有权限const {permissions}=to。meta if(权限){ const hasPermission=include permission(权限)if(!has permission)next({ name : ' no permission ' })} next()} } else { next({ name 3360 ' log in ' })})我们可以看到我们需要一个判断权限的方法。vuex中的getPermissionList如下:

//@/storeexport默认值{ state : { permissionlist :[]},经过必要的修改后: { updatepermissionlist :(state,payload)={ state . permissionlist=payload } },actions 3360 { getpermissionlist : async({ state,Commit })={//这是为了防止重复获取if (state。permissionlist . length)return//发送请求方法省略const List=awa tapi . getpermissionlist()commit(' updatePermissionList ',List)} }//@/utils/permission import store from ' @/store/* * *判断你是否有权限* @ param { array sting } permissions-判断权限列表*/Function include permissions(permissions=[]){//如果这里要判断的权限没有设置,就表示不需要权限,如果(!permissions.length)返回true const permissions list=store . state . permissions list返回!权限。find (permission=权限列表。包括(权限))}重定向问题

以上,我们已经解决了路由的基本配置,如何获取权限,以及如何限制路由跳数。接下来,我们必须处理重定向。这可能与我们项目本身的架构有关。我们项目的侧边栏下有孩子,如下图中的标签切换所示。正常情况下,点击药品管理时,页面会重定向到仓储管理的页签切换页面,但是当仓储管理没有权限时,应该直接重定向到出库管理界面。

因此,为了达到上述效果,我需要重写路由器的重定向,以便动态判断(因为我在配置路由时不知道当前用户的权限列表)

然后我查看了vue-router的文档,发现重定向是一种可以解决重定向问题的方法。

vue-router中的重定向显示,我们可以将重定向重写如下:

//我们需要引入判断权限方法从@/utils/permission ' const children=[{ path : ' list ',name: 'UserList ',label: '导入{ includePermission }用户列表,元: {权限3360[' U _ 1 _ 1 ']},{路径: '组',名称: '用户组',标签: '用户组,meta : { permissions 3360[' U _ 1 _ 2 ']}]const routeDemo={ path : '/User ',name: 'User ',label: '用户,重定向:(到)={ if(包含权限(子项[0])。梅塔。权限))返回{ name:儿童[0]} .name } if(包括权限(子项[1]。梅塔。权限))返回{ name : children[1]} .姓名} },孩子}虽然问题解决了,但是发现这样写下去很麻烦,还要修改路由器的配置,所以我们使用一个方法生成:

//@/utils/permission/** *创建重定向函数* @param {Object}重定向-重定向对象* @param {string}重定向。名字-重定向的组件名称* @param {Arrayany}孩子-子列表*/函数createRedirectFn(重定向={},子项=[]) { //避免缓存太大,只保留孩子们的名字和权限const权限children=children。map(({ name=' ',meta : { permissions=[]}={ } })=({ name,permissions }))返回函数(至){ //这里一定不能在返回的函数外面筛选,因为权限是异步获取的const haspermissions子级=permissions子级。筛选器(项=包含权限(项。权限))//默认填写的重定向的name const DefaultNAmE=重定向。名称| | ' '//如果默认重定向没有权限,则从孩子们中选择第一个有权限的路由做重定向const first permissions name=(has permissions子项[0]| | { name : ' ' }).名称/判断是否需要修改默认的重定向const saveDefaultName=!haspermissionchildren。查找(项目=项目。name===默认名称默认名称)如果(保存默认名称)返回{ name: defaultName }否则返回firstPermissionName?{名称:第一权限名称} :重定向}}然后我们就可以改写为:

//我们需要引入判断权限方法从@/utils/permission ' const children=[{ path : ' list ',name: 'UserList ',label: '导入{ includePermission,createRedirectFn }用户列表,元: {权限3360[' U _ 1 _ 1 ']},{路径: '组',名称: '用户组',标签: '用户组,meta : { permissions 3360[' U _ 1 _ 2 ']}]const routeDemo={ path : '/User ',name: 'User ',label: '用户,重定向: createdirectfn({ name : ' user rist ' },children),children}这样稍微简洁一些,但我还是需要一个一个路由去修改,所以我又写了一个方法来递归路由器配置,并重写他们的重定向:

//@/utils/permission/** *创建有权限的路由配置(多级)* @param {Object}配置-路由配置对象* @param {Object}配置。重定向-必须是孩子们中的一个,并且使用name */function createPermissionRouter({ redirect,children=[],others }){ const needrecury=!孩子们。长度if(NeedRefrequency){ return }.其他,redirect: createRedirectFn(重定向,子级),孩子:个孩子。map(item=createPermissionRouter(item))} } else { return }.其他,重定向} }}这样我们只需要在最外层的路由器配置加上这样一层函数就可以了:

从' @/utils/permission ' const routes Config=[{ path : '/User ',name:' user ',label:' user ',meta : { permissions 3360[' U _ 1 ']},redirect : { name: 'UserList ' },children: [ { path: 'list ',name : ' User List ',label:导入{ createpermissionrouter } Name: '用户组配置',Label: '用户组设置',meta : { permissions 3360[' U _ 1 _ 2 _ 2 ']} }]} }]导出Const routes=routes Config . map(item=createPermissionRouter(item))Const router=new vue router({ routes })导出默认路由器。 当然,写这个还有一个好处。事实上,您不需要设置重定向,它会自动重定向到第一个授权的子路由

侧边栏显示了这个问题

在我们的项目中,边栏是根据路由配置生成的。当然,还会添加一些其他参数来显示显示层次结构和其他问题,所以这里不写具体的代码。如何解决侧边栏中的所有孩子未经允许不显示的问题?

我在这里的想法是将路由配置更新到vuex,然后从vuex中的配置中读取侧边栏配置。

既然这个地方要修改的东西很多,而且涉及到业务,我就不把代码拿出来了,大家可以自己实验。

一种便于团队部署权限点的方法

上面的权限问题我们已经解决了大部分,所以涉及业务逻辑的权限点部署还是有很多的。因此,为了让团队中的其他人优雅而简单地将权限点部署到各个页面,我提供了以下方法在项目中部署权限:

通过指令v-权限直接在模板上设置

Div v-permission='['U_1']'/div由全局方法this判断。$permission,因为有些权限不在模板中

{hasPermission () {//使用方法$permission判断您是否有权返回这个。$permission (['u _ 1 _ 1 ',' u _ 1 _ 2'])}}这里需要注意的是,为了监控$permission方法的返回值,有必要从这一点来判断。判断时$store。下面是实现

//@/utils/permission/** *判断你是否有权限* @ param {arraystring | number}权限-待判断的权限列表* @ param { Object } permissions list-传入存储实现数据监控的权限列表*/函数includepermissionwithore(permissions=[],permissionList=[]) { if(!permissions.length)返回true返回!permissions . find(permissions=permissionlist . includes(permissions))}从“@/utils/permissions”导入{ include permissions }导出默认{ install (Vue,options){ Vue . prototype . $ permissions=function(permissions){ const permissions list=this。$ store . state . permission list return includepermissionstore(permissions,permissions list)} }以下是指令的实现代码(为了不与v-if冲突,这里的显示和隐藏是通过添加/删除className来控制的):

//@/指令/permissions import { include permissions }来自' @/utils/permissions ' const permissions handle=(El,binding)={ const permissions=binding . value if(!包含权限(permission)){ El . class list . add(' hide ')} else { El . class list . remove(' hide ')} }导出默认{插入:权限句柄,更新:权限句柄}摘要

鉴于上述问题,现总结如下:

1、何时获取权限列表,如何存储权限列表

Router.beforeEach每个都被获取并存储在vuex中。

2.当所有子路由都没有权限时,不应显示它们(例如,当用户列表和用户设置没有权限时,用户不应显示在侧栏中)

通过在vuex中存储路由配置,生成侧边栏设置,获得权限后在vuex中修改配置控件显示和隐藏。

3.如果默认重定向路由没有权限,您应该在子路由中查找有权限的重定向(例如,用户路由应该重定向到用户列表路由,如果用户列表没有权限,则应该重定向到用户组路由)

这可以通过在虚拟路由器中设置重定向到函数来实现

4.当用户未经允许直接输入网址时,他需要未经允许跳转到页面或进行其他操作。(路由限制)

在meta中设置权限,在router中判断权限.

以上是我对这个权限要求的一般解决方案和代码实现,可能不太完善,但还是希望能对大家有所帮助_

好了,这就是本文的全部内容。希望本文的内容对你的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:如何优雅地添加vue中的权限控制示例是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。