Pro 的 Layout 组件

chenshuai2144afc163
上次修改时间:2021-05-07 14:47:80

在 Pro 中一直存在一个问题,我们将整个项目交给了用户,虽然提升了用户的 DIY 的能力,可以让用户对任何功能修改,完全掌控项目。但是也会让用户需要了解很多细节。并且无法快速的进行版本的升级。

尤其是 Pro 的核心 Layout,作为 Pro 的中使用最多的一块,在业务支持中我们见到了几乎的各个时期的版本。 0.x,1.x,2.x,几乎每个版本都有用户,但是却无法跟随官方升级,只能发生了错误之后再官方社区提供帮助。

在 V4 中我们提供了一个解决方案。将 Layout 进行组件化,既可以让任何脚手架使用 Layout 的能力,同时也可以平滑升级,跟进社区的发展。代码仓库在这里 pro-layout

ProLayout 提供了丰富的 api 配置,解耦了对 umi 的依赖,即使是旧的项目也可以快速接入。

使用

使用 layout:

npm i @ant-design/pro-layout --save
// or
yarn add @ant-design/pro-layout

在 jsx 中:

import BasicLayout from '@ant-design/pro-layout';

render(<BasicLayout title="Ant Design Pro" />, document.getElementById('root'));

启动项目,你就可以得到

image

高级用法

Layout 有很多需要自定义的需求,所以我们暴露了一系列的方法,希望在灵活和简单之间找到一个平衡。Layout 的一系列 Api 都有预设值,不需要特殊配置也可以正常运行。

自定义菜单

Layout 通过 route props 来生成菜单,如果你使用的是 umi 在 prop 中或自带这个参数。你可以这样使用:

const Layout = (props: BasicLayoutProps) => {
  return <BasicLayout title="Ant Design Pro" {...props} />;
};

如果你使用的其他脚手架,你可以将路由配置手动传入,数据结构如下:

// can be imported { RouterTypes } from '@ant-design/pro-layout/typings'  to get this type
export interface Route {
  path?: string;
  routes: Array<{
    exact?: boolean;
    icon?: string;
    name?: string;
    path: string;
    // optional secondary menu
    children?: Route['routes'];
  }>;
}

const route: Route = {
  routes: [
    { path: '/', name: 'welcome', icon: 'smile' },
    { path: '/home', name: '主页', icon: 'home' },
  ],
};

const Layout = (props: BasicLayoutProps) => {
  return <BasicLayout title="Ant Design Pro" {...props} route={route} />;
};

作为补充,我们还提供了 menuDataRendermenuItemRender props,

menuDataRender 进行对菜单数据再进行一次筛选,Pro 中菜单权限就是通过这种方式实现的。

export interface MenuDataItem {
  authority?: string[] | string;
  children?: MenuDataItem[];
  hideChildrenInMenu?: boolean;
  hideInMenu?: boolean;
  icon?: string;
  locale?: string;
  name?: string;
  path: string;
}

const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] => {
  return menuList.map((item) => {
    const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] };
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
  });
};
const Layout = (props: BasicLayoutProps) => {
  return <BasicLayout title="Ant Design Pro" menuDataRender={menuDataRender} />;
};

menuItemRender 控制具体的菜单 dom 渲染,你可以自定义 menuItem 的点击事件等等。

export interface MenuDataItem {
  authority?: string[] | string;
  children?: MenuDataItem[];
  hideChildrenInMenu?: boolean;
  hideInMenu?: boolean;
  icon?: string;
  locale?: string;
  name?: string;
  path: string;
}

const Layout = (props: BasicLayoutProps) => {
  return (
    <BasicLayout
      title="Ant Design Pro"
      menuItemRender={(menuItemProps, defaultDom) => {
        return <Link to={menuItemProps.path}>{defaultDom}</Link>;
      }}
    />
  );
};

SettingDrawer

SettingDrawer 提供了一个界面来动态的设置 Layout 的一些参数。具体效果可以在 preview 预览效果。使用方式也很简单。

import BasicLayout, { SettingDrawer } from '@ant-design/pro-layout';
import React, { useState } from 'react';

const Layout = (props: BasicLayoutProps) => {
  const [settings, setSettings] = useState({});
  return (
    <>
      <BasicLayout
        {...settings}
        title="Ant Design Pro"
        menuItemRender={(menuItemProps, defaultDom) => {
          return <Link to={menuItemProps.path}>{defaultDom}</Link>;
        }}
      />
      <SettingDrawer settings={settings} onSettingChange={setSettings} />
    </>
  );
};

PageContainer

PageContainer 提供了对 antd 的 pageHeader 的封装提供了面包屑和 title 的自动配置。

import { PageContainer } from '@ant-design/pro-layout';

const Page = () => <PageContainer>this is a page</PageContainer>;

RouteContext

RouteContext 可以提供 Layout 的内置的数据。例如 isMobile 和 collapsed,你可以消费这些数据来自定义一些行为。

import { RouteContext } from '@ant-design/pro-layout';

const Page = () => (
  <RouteContext.Consumer>
    {(value) => {
      return value.title;
    }}
  </RouteContext.Consumer>
);