# @fesjs/plugin-access ## 介绍 对于前端应用来说,权限就是页面、页面元素是否可见。 ### 资源 Fes.js 把页面、页面元素统一叫做资源,用资源 ID 来识别区分他们: - 页面的资源 ID 默认是页面的路由 `path` 。比如页面 `pages/a.vue` 的路由 `path` 是 `/a`。当页面访问 `/a` 时会渲染当前页面,`/a` 也就是页面的 `accessId`。 - 页面元素的资源 ID 没有默认值,需要自定义。 ```vue ``` ### 匹配规则 #### 全等匹配 资源的匹配规则默认是使用全等匹配,比如页面 `pages/a.vue` 对应路由 `path` 是 `/a`,则 `/a` 就是页面的资源ID。如果我们设置: ```js access.setAccess(['/a']) ``` 由于权限列表中包含`/a`,则表示拥有此页面权限。 #### 模糊匹配 页面`@id.vue`会映射为动态路由`/:id`,想匹配此页面有两种办法: - **access.setAccess(['/:id'])** - **access.setAccess(['/*'])** 第二种是模糊匹配,`*`表示任意路径。比如角色`admin`需要全部权限,则可以: ```js export default { access: { roles: { admin: ["*"] } } } ``` ### 角色 通常我们会用角色来控制权限,相应的Fes.js 用角色定义一组资源。当访问 Fes.js 应用时,使用插件提供的 API 设置用户的角色,角色对应的资源才可见,非角色对应的资源不可见。 当然有时候业务比较复杂,角色对应的权限是动态的。不要怕!插件提供粒度更细的 API 来设置当前用户能访问的资源。 ## 启用方式 在 `package.json` 中引入依赖: ```json { "dependencies": { "@fesjs/fes": "^2.0.0", "@fesjs/plugin-access": "^2.0.0" }, } ``` ## 编译时配置 在执行 `fes dev` 或者 `fes build` 时,通过此配置生成运行时的代码,在配置文件`.fes.js` 中配置: ```js export default { access: { roles: { admin: ["/", "/onepiece", '/store'] } } } ``` ### roles - **类型**:对象 - **默认值**:`{}` - **详情**: 角色预定义列表。`key` 是角色 Id ,`value`是角色 Id 对应的资源列表。 ## 运行时配置 在 `app.js` 中配置 ### unAccessHandler - **类型**:`Function` - **默认值**:`null` - **详情**: 当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。 - **参数** - router:createRouter 创建的路由实例 - to: 准备进入的路由 - from:离开的路由 - next: [next函数](https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%8F%AF%E9%80%89%E7%9A%84%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0-next) 比如: ```js export const access = { unAccessHandler({ to, next }) { const accesssIds = accessApi.getAccess(); if (to.path === '/404') { accessApi.setAccess(accesssIds.concat(['/404'])); return next('/404'); } if (!accesssIds.includes('/403')) { accessApi.setAccess(accesssIds.concat(['/403'])); } next('/403'); } }; ``` ### noFoundHandler - **类型**:`Function` - **默认值**:`null` - **详情**: 当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。 - **参数** - router:createRouter 创建的路由实例 - to: 准备进入的路由 - from:离开的路由 - next: [next函数](https://next.router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%8F%AF%E9%80%89%E7%9A%84%E7%AC%AC%E4%B8%89%E4%B8%AA%E5%8F%82%E6%95%B0-next) 比如: ```js export const access = { noFoundHandler({ next }) { const accesssIds = accessApi.getAccess(); if (!accesssIds.includes('/404')) { accessApi.setAccess(accesssIds.concat(['/404'])); } next('/404'); } }; ``` ## API ### access 插件 API 通过 `@fesjs/fes` 导出: ```js import { access } from '@fesjs/fes' ``` #### access.hasAccess - **类型**:函数 - **详情**: 判断某个资源是否可见。 - **参数**: - accessId,资源Id - **返回值**:Boolean #### access.isDataReady - **类型**:函数 - **详情**:可以用异步数据来设置权限,`isDataReady` 用来判断异步数据是否已经加载完毕。 - **参数**:null - **返回值**:Boolean ```js import { access } from '@fesjs/fes'; console.log(access.isDataReady()) ``` #### access.setRole - **类型**:函数 - **详情**:设置当前的角色。 - **参数**: - roleId,角色Id,有两种类型: - String,对应着 `roles` 配置对象中的 `key`。 - Promise,Promise resolve 的结果应对应着 `roles` 配置对象中的 `key`。 ```js import { access } from '@fesjs/fes'; access.setRole('admin') ``` #### access.setAccess - **类型**:函数 - **详情**:设置当前的角色。 - **参数**: - accessIds,资源Id数组,有两种类型: - Array,数组项对应着 `roles` 配置对象中的 `key`。 - Promise,Promise resolve 的结果应该是`Array`。 ```js import { access } from '@fesjs/fes'; access.setAccess(['/a', '/b', '/c']) ``` #### access.getAccess - **类型**:函数 - **详情**:返回当前可见的资源列表。 - **参数**:null ```js import { access } from '@fesjs/fes'; access.getAccess(); ``` ### useAccess - **类型**:[composition]((https://v3.cn.vuejs.org/guide/composition-api-introduction.html)) 函数 - **详情**:判断某个资源是否可见。 - **参数**: - accessId,资源Id - **返回值**:`ref` ```vue ``` ### v-access 在指令 `v-access` 中传入 `accessId`,则当 `accessId` 拥有权限时显示DOM,当没有权限时隐藏此DOM。 ```vue ``` ### 组件 Access 组件 `Access` 中传入 `accessId`,则当 `accessId` 拥有权限时渲染此组件,当没有权限时隐藏此组件。 ```vue ```