umi框架,prolayout布局,access设置菜单权限,initialState全局初始化数据,配合使用,根据后端返回的权限信息,完成菜单的不同的权限的不同展示。
1. umi 配合 patlayout 布局, 实现根据配置的路由展示菜单栏
2. umi 的 access 插件,设置不同权限的菜单展示
3. 没有redux 仓库,通过 initialState 全局初始化数据,完成登陆后权限信息的保存、获取
4. 总体流程:
① 在app.tsx文件里,设置并导出 initialState 数据,其中有获取权限的方法,以及获取的权限字段
② 登录时调用 initialState 数据里的,调取接口方法,修改全局初始化里的权限值
② access插件,配合pro-layout ,设置路由菜单,根据 initialState 数据里的权限值,配置access 值,设置菜单权限
③ 每次刷新时,重新调用initialState 里的获取权限 方法
一、umi插件 access,配合pro-layout, 路由完成菜单、权限配置
1. 配置pro-layout
① 安装@ant-design/pro-layout
② 配置 layout:{}
see (快速上手-修改配置)--> https://v3.umijs.org/zh-CN/docs/getting-started
③ Pro 中默认会读取 config/config.tsx 中的 routes 配置作为 ProLayout 的菜单数据来生成菜单。routes 里配置name属性的,会被生成菜单,无name属性的既普通路由
2. access 插件--umijs/plugin-access
路由配合配合 plugin-access 还可以很方便的进行菜单的权限管理。在菜单中配置access属性,字段结果为真时,菜单可见,为假,菜单不可见。
{
path: '/dashboardHouse',
name: '工作台',
icon: 'dashboard',
access: 'isDashboardHouse',
component: './dashboardHouse/dashboard',
},
access介绍:约定了 src/access.ts
为我们的权限定义文件,该文件需要默认导出一个方法,导出的方法会在项目初始化时被执行。该方法需要返回一个对象,对象的每一个值就对应定义了一条权限。 如图,在access里,取全局初始化数据umijs/plugin-initial-state里的权限信息进行匹配。
二、利用 umijs/plugin-initial-state 进行权限信息的储存
1. umi插件--umijs/plugin-initial-state 介绍
①约定一个地方生产和消费初始化数据。
②有 src/app.ts
并且导出 getInitialState
方法时启用。
③本插件不可直接使用,必须搭配 @umijs/plugin-model
一起使用。
④配置:
⑤ 在组件中获取值
2. 使用
① 在 src/app.ts
设置并导出 getInitialState
方法时(启用)
getInitialState 中的
fetchUserInfo 中的方法
,是调用权限的方法/接口
登陆时,本地存储name ,后面每次刷新时,从本地获取name ,调用getInitialState的权限方法
/**将/api/currentUser接口返回的信息存入全局初始数据initialState */
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
menus?: [];
//请求用户信息
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
const fetchUserInfo = async () => {
const name = window.sessionStorage.getItem('name')
try {
const res = await getCurrentUser({ name });
if (res?.success) {
const { data:{ids,code} } = res
const currentUser = {currentAuthority:ids,code}
return currentUser;
}
} catch (error) {
// history.push(loginPath);
}
return undefined;
};
// // 如果是登录页面,不执行
if (history.location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
currentUser,
fetchUserInfo,
settings: {},
};
}
return {
settings: {},
fetchUserInfo
};
② 登录,调用initialState 数据,调用 fetchUserInfo 获取权限(修改权限信息)
const { initialState, setInitialState } = useModel('@@initialState');
/**登陆后--获取权限--调权限接口 */
const fetchUserInfo = async () => {
const userInfo = await initialState?.fetchUserInfo?.();
if (userInfo) {
setInitialState({
...initialState,
currentUser: userInfo,
});
}
}
// 点击登录
const handleSubmit = async (values: API.LoginParams) => {
var storage = window.sessionStorage;
const { name, password } = values
// 登录接口
const res = await logIn({ name, password })
if (res?.success) {
setSubmitting(true);
storage.setItem('name', name)
await fetchUserInfo();
}
三、initial-state 配合使用的 umijs/plugin-model 插件
①
一种基于 hooks
范式的简易数据管理方案(部分场景可以取代 dva
),通常用于中台项目的全局共享数据。
② src/models
目录下有 hooks model 时启用。
四、页面权限分配
上面介绍了access 的权限设置,access插件还可以利用 hook -- useAccess 用于在组件中获取权限相关信息, 与组件Access 完成页面权限的分配。(此时,其他信息也可存储到access里,其他地方可以进行引用,例如code)
<Access>
组件拥有 accessible
和 fallback
两个属性,当 accessible
为 true
时会渲染子组件,当 accessible
为 false
会渲染 fallback
属性对应的 ReactNode
。
import { useAccess, Access } from 'umi';
const access = useAccess()
const code = access.code
<Access
accessible={access.isDashboardCenterQuick}
fallback ={null}
>
<Button type="dashed" icon={<PlusOutlined />} onClick={showModal}>
添加
</Button>
</Access>
五、路由鉴权
设置高阶组件,可以通过参数route 取出当前路由的 access,在利用useAccess, 可以获得当前路由权限,实现路由鉴权
{
path: '/system',
name: '系统管理',
icon: 'setting',
access: 'isSystem',
wrappers: ['@/wrappers/auth'],
}
// config,里的 路由设置