ProLayout 高级布局是 Ant Design Pro 中的一个组件,可以提供一个标准又不失灵活的中后台标准布局,同时提供一键切换布局形态,自动生成菜单等功能。页面中需要承载内容时,可以使用 ProLayout 来减少布局成本。
项目使用 Umi 开发,Umi 是集成了 Antd Pro 的,但是在使用 ProLayout 生成菜单时遇到亿点点问题,记录一下。
使用 umirc.ts 直接配置路由和 layout :
layout: {
name: 'Ant Design',
locale: true,
layout: 'side',
},
这样是可以正常显示了,但是点击菜单不能进行路由跳转。
需要在 @/layout
中进行定制改造。
在网上查了,其中有一个是菜单图标用的 <Iconfont />
他说自带的 icon
改造起来更麻烦,其实不是的。
首先在 umirc.ts
配置的路由中增加两行:
path: '/',
component: '@/layouts',
增加后大概格式如下:
routes: [
{
path: '/',
component: '@/layouts',
routes: [
{
name: '首页',
path: '/',
icon:'home',
component: '@/pages/index',
},
...
],
},
],
然后在 /src
目录下创建一个 layouts
文件夹:注意是 layouts
不是 layout
└─ src
└─ layouts
├─ index.tsx
└─ index.less
@/src/layouts/index.tsx
import React, { useState } from 'react';
import type { ProSettings } from '@ant-design/pro-layout';
import ProLayout, { PageContainer, MenuDataItem } from '@ant-design/pro-layout';
import { IconMap } from '@/utils/iconsMap';
import { Link } from 'umi';
const BasicLayout: React.FC<{}> = (props) => {
const { route } = props;
const [settings, setSetting] = useState<Partial<ProSettings> | undefined>({
fixSiderbar: true,
title: '前端资源网',
});
// 菜单 loop
const loopMenuItem = (menus: MenuDataItem[]): MenuDataItem[] =>
menus.map(({ icon, children, ...item }) => ({
...item,
icon: icon && IconMap[icon as string],
children: children && loopMenuItem(children),
}));
return (
<ProLayout
logo={require('@/assets/logo.svg')}
contentStyle={{height: 'calc(100vh - 100px)'}}
menuDataRender={() => loopMenuItem(route.routes)}
menuItemRender={(item, dom) => (
<Link to={item.path ?? '/'}>
{dom}
</Link>
)}
{...settings}
>
<PageContainer>{props.children}</PageContainer>
</ProLayout>
);
};
export default BasicLayout;
menuDataRender
是渲染菜单,menuItemRender
是渲染单行的内容。
在 props
中可以取到 umirc.ts
中配置的信息,直接拿到 routes
。
这里的图标如果直接取官方的 type
(如 HomeFilled
)是不行的。
因为这里的 icon
需要是 ReactNode
的形式(如 <HomeFilled />
),但是 umirc.ts
中好像不支持这样写,会报错。
所以需要用 IconMap
转一下,我封装成了一个工具,放在 @/utils
里了:这里的 key
值和 umirc.ts
中 route
的 icon
对应。
import { HomeFilled, SettingFilled } from '@ant-design/icons';
// 菜单图标
export const IconMap = {
home: <HomeFilled />,
setting: <SettingFilled />,
};
这里的 menuItemRender
负责修改菜单的 Item
,方法有两个参数,一个是 item
,包含菜单的配置信息(如 path
, name
等),可以直接用 Link
组件实现路由跳转。
第二个是 dom
就是菜单原始的内容,直接用 Link
包裹起来就可以了。最终效果如下:
另外 <PageContainer />
是右侧的内容,用它将 props.children
包裹即可。
整理不易,搭建这个项目经历了千辛万苦,终于捋清楚了。遇到了使用 ProLayout 左侧菜单不显示、图标显示异常、点击菜单无反应等一系列问题。
如果本文对你有用,欢迎点赞、分享,也可以扫描文章左侧的二维码给我打赏,有任何问题可以在文章下方评论交流。
未经允许不得转载:w3h5-Web前端开发资源网 » Uni&antd的ProLayout布局动态菜单实现及踩坑记录