ant design pro v5 自定义侧边栏收缩按钮位置
图:
1.升级ant design pro v5以后layout隐藏,相关配置放到了app.tsx
layout 的配置代码如下:
export const layout: RunTimeLayoutConfig = ({ 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,
};
};
通过官方文档
我们主要关注红框里面的参数。
那么我们开始动手:
- 首先在 components 下新增 HeaderContent.
import React from 'react';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
export type HeaderContent = {
collapse?: boolean;
onCollapse?: (collapsed: boolean) => void;
};
// eslint-disable-next-line @typescript-eslint/no-redeclare
const HeaderContent: React.FC<HeaderContent> = (props) => {
const [collapsed, setCollapsed] = useMergedState<boolean>(props.collapse ?? false, {
value: props.collapse,
onChange: props.onCollapse,
});
return (
<>
<div
onClick={() => setCollapsed(!collapsed)}
style={{
cursor: 'pointer',
fontSize: '16px',
}}
>
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</div>
</>
);
};
export default HeaderContent;
- 修改 app.tsx 下getInitialState() 方法。
新增collapsed?: boolean;
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
collapsed?: boolean;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
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: {},
};
}
3.修改 RunTimeLayoutConfig 改动地方我都加了注释。
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
const onCollapse = (collapsed: boolean): void => {
setInitialState({ ...initialState, collapsed }).then();
};
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
// 自定义头内容的方法 我把 自定义侧边栏收缩按钮位置 方在这里
headerContentRender: () => (
<HeaderContent collapse={initialState?.collapsed} onCollapse={onCollapse} />
),
// 去掉系统自带
collapsedButtonRender: false,
// 指定配置collapsed
collapsed: initialState?.collapsed,
// 菜单的折叠收起事件
onCollapse: onCollapse,
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
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,
...initialState?.settings,
};
4.修改后整个app.tsx 代码如下:
import type { Settings as LayoutSettings } from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import type { RunTimeLayoutConfig } from 'umi';
import { history, Link } from 'umi';
import RightContent from '@/components/RightContent';
import Footer from '@/components/Footer';
import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
import { BookOutlined, LinkOutlined } from '@ant-design/icons';
import HeaderContent from "@/components/HeaderContent";
const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
loading: <PageLoading />,
};
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
collapsed?: boolean;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
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: {},
};
}
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
const onCollapse = (collapsed: boolean): void => {
setInitialState({ ...initialState, collapsed }).then();
};
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
headerContentRender: () => (
<HeaderContent collapse={initialState?.collapsed} onCollapse={onCollapse} />
),
collapsedButtonRender: false,
collapsed: initialState?.collapsed,
onCollapse: onCollapse,
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,
};
};
最后git贴出来:
git地址