umi-plugin-access-code 权限code插件
基于umi框架体系编写的一个帮助开发人员管理权限code的插件
在实际的开发过程中。你总是会需要处理关于路由级别甚至是按钮级别、数据级别的权限。 针对这个问题。UMI有提供一个开箱即用的权限插件
当你需要配置路由权限。你只需要再路由中加上access
参数.像这样
// config/route.ts
export const routes = [
{
path: '/pageA',
component: 'PageA',
access: 'canReadPageA', // 权限定义返回值的某个 key
}
]
ps: 你需要同时在src/access.ts
同时声明这个canReadPageA为false
如果你需要关联按钮权限。上述的链接也提供的相应的方案去解决。
看起来 umi的插件已经能够满足我们的要求了。那为什么还会有umi-plugin-access-code
插件呢?
动机(motive)
让我们来看一下关于权限code绑定交互实际开发的流程
- 开发人员手动在路由上绑定 access。 就像上面那样。并且在
src/access.ts
种声明权限code - (可选)如果有按钮级别权限。你需要在
src/access.ts
也预先定义好 - 将你所有的code在资源管理页面中一个!一个!一个!的手动进行创建。并给他们起好名字.像这样
如果你的后管项目只有三五个页面。这个工作或许看起来并不是什么大问题。但是,如果你的项目存在五十六甚至七八十个页面。那么这个工作多少是有那么些枯燥与乏味。
试想一下。这个工作不仅需要花费你大量的时间。如果你创建过程中还创建错了,那么它也会相当的考验你的耐心。
程序员的宗旨是:能够自动化的东西。一律不用手写。为了在权限code管理维护上实现这个目标。umi-plugin-access-code 诞生了。
使用
首先声明。umi-plugin-access-code并没有独立于umi的权限管理另起炉灶。依然是在它的权限模式下去减少上面我们提到的开发人员的工作量。如果你不愿意使用。你依然可以无缝的切换到最初的模式。
这个插件默认内置到框架中并且默认启动了。
你可以在package.json
中找到这个依赖。并且在config/config.ts
中看到插件相关的配置
// ...ignore others
accessCodes: {
routeInject: REACT_APP_ENV !== 'dev',
exclude: ['home', 'login', 'user-setting', 'user-notices', 'sysSetting-resourcesManagement'],
sql: true
},
运行
在项目目录下运行命令
yann|pnpm code
当你运行命令 yarn code
时,这将会在src/access.ts
中根据路由路径以及额外信息。生成所有的access code。并且会有一段CODE_START
的标注。像这样:
并且如果你的sql设置为true。会同时在src
目录下生成一份access.sql
文件。下面我们也会详细解释
配置参数
这个插件很简单。只有三个参数配置。接下来我们挨个介绍
routeInejct 路由注入
上面我们提到。如果你需要配置路由级的权限。那你就要在路由上写上access: xxx
来绑定对应的code。所以首先就通过 routeInejct 配置来解决这里的手动编写的问题
让我们来举个例子。让你直观的理解这个过程。假设我们有这么一个路由
// config/route.ts
export const routes = [
{
path: '/page',
component: 'Page',
access: 'page', // 权限定义返回值的某个 key
children: [{
path: '/page/child',
component: 'Page/child',
access: 'pageChild', // 权限定义返回值的某个 key
}]
}
]
我们发现。我们完全可以将access的值按照特殊的规则(即:组合path,删除斜杠并且子级首字母大写的方式)来定义。这样既直观。而且也非常可靠好记。
既然有这种规律的模式。那我们是不是可以将这个行为自动化? 所以。当你设置 routeInejct: true
时。那么在项目启动编译时。我们可以动态的改写运行时路由代码。将access参数按照特定的规则动态写入。这样你就不用手动的一个一个的编写access参数了
// config/route.ts
export const routes = [
{
path: '/page',
component: 'Page',
// access: 'page', // 不用写了。插件会帮你写上
children: [{
path: '/page/child',
component: 'Page/child',
// access: 'pageChild', // 不用写了。插件会帮你写上
}]
}
]
事实上。我们设置的是 routeInject: REACT_APP_ENV !== 'dev'。表示开发环境时不注入。所有权限都会开放。这样方便开发工作
exclude 排除
有了上面的例子。我们知道。所有的path都会被绑定access
参数。但是有些公共页面。比如登录注册等不需要绑定权限的路由页面也会被关联照顾。为了解决误伤的问题。你可以通过exclude
参数。传递不需要绑定的code.
sql
上面的操作。我们解决了手动编写路由表中 access
与src/access.ts
这两处的工作。那么。在资源管理页面手动创建code的工作。我们还没解决。所以,这个配置参数就是用来解决这最后问题的。
当你设置sql: true
时。 运行 yarn code
会在src/access.ts
中生成一份code。同时会在同级下生成一份access.sql
脚本文件。
此时你可以将这份脚本文件提供给后端同学。让他在数据库中运行一下。 这时候。你再去刷新一下资源管理页面。 你会惊奇的发现。所有的资源都已经创建好了。并且帮你正确的关联了父子级关系!
按钮级权限绑定
有时候你不仅只是需要绑定菜单路由权限。业务需要更加细粒度的控制。比如说到按钮基本的操作权限。此时,我们就需要扩展这一需求。如何来做呢?
其实也非常简单。我们只需要在页面路由中加入operationAccess
扩展参数即可。
export default [
{
name: '基础设置',
path: '/basicSetting',
routes: [
{
name: '素材库',
path: '/basicSetting/materialLibrary',
component: './basicSetting/materialLibrary',
// 按钮级权限绑定
operationAccess: [
{name:'新增', code: 'add'},
{name:'编辑', code: 'edit'},
{name:'删除', code: 'delete'},
{name:'查看', code: 'view'}
]
}
]
}
]
上面的示例最终会在路径的基础上扩展出四个按钮权限code。并帮你完成注入。
// src/access.ts
export const codes = [
'basicSetting',
'basicSetting-materialLibrary',
'basicSetting-materialLibrary-add',
'basicSetting-materialLibrary-edit',
'basicSetting-materialLibrary-delete',
'basicSetting-materialLibrary-view',
]
当然按钮的权限 你依然需要配合UMI框架中的 <Access>
组件或者 useAccess
hook来使用
结尾
至此。本插件的使用与实现细节。都已经完全讲完了。正如开头所说。他只是帮助你解决开发效率问题的。如果你不喜欢。你完全可以回到手动的模式。按照umi提供的文档去管理你的权限