Uni&antd的ProLayout布局动态菜单实现及踩坑记录

2021-07-09 17:07:55 浏览数 (1)

ProLayout 高级布局是 Ant Design Pro 中的一个组件,可以提供一个标准又不失灵活的中后台标准布局,同时提供一键切换布局形态,自动生成菜单等功能。页面中需要承载内容时,可以使用 ProLayout 来减少布局成本。

项目使用 Umi 开发,Umi 是集成了 Antd Pro 的,但是在使用 ProLayout 生成菜单时遇到亿点点问题,记录一下。

使用 umirc.ts 直接配置路由和 layout :

代码语言:javascript复制
layout: {
  name: 'Ant Design',
  locale: true,
  layout: 'side',
},

这样是可以正常显示了,但是点击菜单不能进行路由跳转。

需要在 @/layout 中进行定制改造。

在网上查了,其中有一个是菜单图标用的 <Iconfont /> 他说自带的 icon 改造起来更麻烦,其实不是的。

ProLayout 高级布局改造,动态菜单,支持菜单加图标

首先在 umirc.ts 配置的路由中增加两行:

代码语言:javascript复制
path: '/',
component: '@/layouts',

增加后大概格式如下:

代码语言:javascript复制
routes: [
  {
    path: '/',
    component: '@/layouts',
    routes: [
      {
        name: '首页',
        path: '/',
        icon:'home',
        component: '@/pages/index',
      },
      ...
    ],
  },
],

然后在 /src 目录下创建一个 layouts 文件夹:注意是 layouts 不是 layout

代码语言:javascript复制
└─ src
    └─ layouts
     ├─ index.tsx
     └─ index.less

@/src/layouts/index.tsx

代码语言:javascript复制
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.tsrouteicon 对应。

代码语言:javascript复制
import { HomeFilled, SettingFilled } from '@ant-design/icons';

// 菜单图标
export const IconMap = {
  home: <HomeFilled />,
  setting: <SettingFilled />,
};

这里的 menuItemRender 负责修改菜单的 Item ,方法有两个参数,一个是 item ,包含菜单的配置信息(如 pathname 等),可以直接用 Link 组件实现路由跳转。

第二个是 dom 就是菜单原始的内容,直接用 Link 包裹起来就可以了。最终效果如下:

另外 <PageContainer /> 是右侧的内容,用它将 props.children 包裹即可。

整理不易,搭建这个项目经历了千辛万苦,终于捋清楚了。遇到了使用 ProLayout 左侧菜单不显示、图标显示异常、点击菜单无反应等一系列问题。

如果本文对你有用,欢迎点赞、分享,也可以扫描文章左侧的二维码给我打赏,有任何问题可以在文章下方评论交流。

未经允许不得转载:w3h5 » Uni&antd的ProLayout布局动态菜单实现及踩坑记录

0 人点赞