1.全局初始数据概念参考官网
https://pro.ant.design/zh-CN/docs/initial-state
2.关于全局初始数据,我个人是这么理解的
在app.jsx中通过getInitialState()方法可以初始化很多基础数据,如当前登录用户信息,当前用户有权查看的菜单树等等,getInitialState()方法返回的数据最后会被默认注入到一个 namespace 为 @@initialState 的 model 中。可以通过 useModel 这个 hook 来消费它:
import React from 'react';
import { useModel } from 'umi';
import { Spin } from 'antd';
export default () => {
const { initialState, loading, refresh, setInitialState } = useModel('@@initialState');
if (loading) {
return <Spin />;
}
return <div>{initialState.userName}</div>;
};
3.antd pro v5初始化项目中的app.jsx中的getInitialState方法代码如下
export async function getInitialState() {
const fetchUserInfo = async () => {
try {
const msg = await queryCurrentUser();
return msg.data;
} catch (error) {
history.push(loginPath);
}
return undefined;
}; // 如果是登录页面,不执行
if (history.location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
settings: {},
};
}
return {
fetchUserInfo,
settings: {},
};
}
会调用queryCurrentUser()方法获取用户信息currentUser(mock数据),并将currentUser,settings数据放入
initialState中,initialState是一个对象类型,里面可以接受任何的子对象(后续我们的动态菜单树)也会放入initialState中。
4.app.jsx中的layout直接消费了initialState,具体代码如下
export const layout = ({ initialState }) => {
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history; // 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
links: isDev
? [
<Link to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<span>OpenAPI 文档</span>
</Link>,
<Link to="/~docs">
<BookOutlined />
<span>业务组件文档</span>
</Link>,
]
: [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
...initialState?.settings,
};
};
layout中消费了initialState中的currentUser,如果currentUser无数据且当前不在登录页面,会自动调到登录页,同时这段代码…initialState?.settings,消费了settings。
5.下面我们利用现有的app.jsx的全局初始数据的逻辑开始实现后台登录效果。