Layout is necessary for a middle and back-end application. One layout + ProTable + Form can get a CRUD page.
Plugin-layout is built into Pro to reduce boilerplate code. In easy use, we only need to configure the layout attribute in config.ts
to achieve a common page layout.
The layout plugin supports all configurations of pro-layout.
It is recommended to use the right drawer of Pro site to help you complete the overall style, theme color, navigation mode, and content area related to the layout. Width, fixed Header, fixed side menu, color weak mode and other configuration options. Then paste the copied configuration into the layout configuration.
// config.jsimport { defineConfig } from 'umi';export const config = defineConfig({layout: {name: 'Ant Design Pro',logo: 'https://preview.pro.ant.design/static/logo.f0355d39.svg',// copy from pro sitenavTheme: 'dark',primaryColor: '#1890ff',layout: 'sidemenu',contentWidth: 'Fluid',fixedHeader: false,fixSiderbar: false,title: 'Ant Design Pro',pwa: false,iconfontUrl: '',},});
We can configure the menu in the route to determine whether the current route will be rendered in the menu. Detailed configuration instructions
When you do not need to display in the menu, you can configure hideInMenu on the route or delete the menu-related configuration;
When you don't need to show children, you can configure hideChildrenInMenu on the route;
When you do not need to show yourself, only show children, you can configure flatMenu on the route;
If the menu is not configured, and the name is not configured, the route will not appear in the sidebar.
// config/routes.tsexport default [{path: '/overview',component: 'Overview/index',menu: {name: 'overview',icon: 'testicon',flatMenu: false,hideInMenu: false,hideChildrenInMenu: false,},},];
Enable internationalization through the locale configuration of the layout configuration.
After opening, the menu name configured in the route will be used as the key for the internationalization of the menu name, and the plug-in will search for the text corresponding to menu.[key] in the locales file. The default value is to change the key.
// locale/zh-CN.jsexport default {'menu.overview': 'Overview',};
Username and internationalization can have a default UI through configuration. Internationalization will display the available languages by detecting the files in the locale directory.
User name and avatar information can provide data by configuring global initialization information.
// src/app.tsexport function getInitialState() {return {name: 'Serati Ma',avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png',};}
Logout logic can also be customized through configuration.
// src/app.tsexport const layout = {logout: () => {alert('Log out successfully');},};
If the above requirements cannot be met, the upper right corner UI can be completely customized through the following interface.
// src/app.tsximport React from 'react';export const layout = {rightRender: (initialState, setInitialState) => {// xxxreturn 'xxx';},};
The plugin does not provide a default footer UI. The customization can be done through the following configuration. If you want to use the same style as Pro's official website, please refer to: https://procomponents.ant.design/components/layout#footer
// src/app.tsximport React from 'react';export const layout = {footerRender: () => {// xxxreturn <xxx />;},};
<BasicLayout{...defaultProps}title="Remax"logo="https://gw.alipayobjects.com/mdn/rms_b5fcc5/afts/img/A*1NHAQYduQiQAAAAAAAAAAABkARQnAQ"menuHeaderRender={(logo, title) => (<divid="customize_menu_header"onClick={() => {window.open('https://remaxjs.org/');}}>{logo}{title}</div>)}/>
If you need a custom menu, the siderWidth
property controls the width of the menu on the right, and menuRender
and menuItemRender
let you customize the entire menu. menuDataRender
can be used to customize menu data, which you can replace with data obtained from the server.
master
const layout = ({ children }) => children;export default layout;
We can modify or wrap children. The ProLayout component injects menu and other configurations through such a scheme. What children are is related to your current path and layout configuration in the project. If you can't meet your needs, you can try to adjust the location.
When it is necessary to perform authority control on certain routes, it can be easily implemented with a built-in authority scheme. When a user accesses an unauthorized route, the layout will provide a default unauthorized page.
The detailed configuration scheme can be: click to view
// src/app.tsexport async function getInitialState() {const data = await fetchXXX();return data;}
// src/access.tsimport { InitialState } from 'umi';export default function accessFactory(initialState: InitialState) {return {readArticle: initialState.name === 'haha',};}
// config/route.tsexport default [{path: '/overview',component: 'Overview/index',name: 'overview',icon: 'testicon',access: 'readArticle',},];
The built-in layout will display the default UI for non-existent routes and routes that are not authorized to be accessed. No access as shown above.
When accessing a UI that does not exist, the default UI is as follows
Sometimes our page may have some global general processing logic or UI, we want to complete it before the page is added, usually we hope that we can wrap a layer of layout inside the built-in layout to complete the demand.
// config/routes.tsexport default [{path: '/',component: '../layout/index',menu: {flatMenu: true,},routes: [{path: '/',redirect: '/overview',},{path: '/overview',component: 'Overview/index',menu: {name: 'overview',icon: 'testicon',},},],},];// src/layout/index.tsxconst Layout = ({ children }) => children;export default Layout;
Sometimes our page may have some immersive design, and some layouts need to be hidden for routing. This can be achieved by adding an extended routing configuration. Detailed configuration
// config/route.tsexport default [{path: '/overview',component: 'Overview/index',name: 'overview',icon: 'testicon',layout: {hideMenu: false,hideNav: false,hideFooter: false,},},];
Sometimes our menu may display at top, left or left and top either, This can be achieved by changing layout
at defaultSettings.js.
top Display at top
side Display at left side
mix Display at left and top either,by the way,when the layout mode is mix
, we need add splitMenus: true
at defaultSettings.js
// config/defaultSettings.tsexport default {layout: 'mix',splitMenus: true,};
Tips: When the layout mode is mix
,click the first menu, page cannot route they first children menu page, you can add redirect
at route.
[{"path": "/test/list","component": "./test/list"},{"path": "/test/list/testAdd","component": "./test/list/testAdd"},{"redirect": "./test/list"}]
Sometimes we don't want to use the built-in layout and want to do more customization. We also provide flexible customization solutions.
The layout is essentially a special component, and the child pages will be passed to the layout component as attributes. The easyst layout is this:
// Children must be rendered, otherwise the child routes cannot be displayed// Here you can also set global provisionconst layout = ({ children }) => children;export default layout;
We create a new BaseLayout.tsx in src/layouts/
, copy the above code, and add the following code in config/config.ts
:
defineConfig({// added configurationroutes: {path: '/',component: '.../layouts/BaseLayout',},});
We can modify or wrap children, and the ProLayout component uses such a scheme to inject configuration such as menus. What children are is related to your current path and layout configuration in the project. If you cannot meet your needs, you can try to adjust the location.
The following is the default ProLayout configuration, we can copy the default code and then customize:
/*** Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.** @see You can view component api by: https://github.com/ant-design/ant-design-pro-layout*/import type {MenuDataItem,BasicLayoutProps as ProLayoutProps,Settings,} from '@ant-design/pro-layout';import ProLayout, { DefaultFooter } from '@ant-design/pro-layout';import React from 'react';import { Link } from 'umi';import { GithubOutlined } from '@ant-design/icons';import RightContent from '@/components/GlobalHeader/RightContent';import logo from '../assets/logo.svg';export type BasicLayoutProps = {breadcrumbNameMap: Record<string, MenuDataItem>;route: ProLayoutProps['route'] & {authority: string[];};settings: Settings;} & ProLayoutProps;export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {breadcrumbNameMap: Record<string, MenuDataItem>;};const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>menuList.map((item) => {return {...item,children: item.children ? menuDataRender(item.children) : undefined,};});const defaultFooterDom = (<DefaultFootercopyright={`${new Date().getFullYear()} 蚂蚁集团体验技术部出品`}links={[{key: 'Ant Design Pro',title: 'Ant Design Pro',href: 'https://pro.ant.design',blankTarget: true,},{key: 'github',title: <GithubOutlined />,href: 'https://github.com/ant-design/ant-design-pro',blankTarget: true,},{key: 'Ant Design',title: 'Ant Design',href: 'https://ant.design',blankTarget: true,},]}/>);const BasicLayout: React.FC<BasicLayoutProps> = (props) => {const {children,location = {pathname: '/',},} = props;const { formatMessage } = useIntl();return (<ProLayoutlogo={logo}formatMessage={formatMessage}{...props}onCollapse={handleMenuCollapse}onMenuHeaderClick={() => history.push('/')}menuItemRender={(menuItemProps, defaultDom) => {if (menuItemProps.isUrl ||!menuItemProps.path ||location.pathname === menuItemProps.path) {return defaultDom;}return <Link to={menuItemProps.path}>{defaultDom}</Link>;}}breadcrumbRender={(routers = []) => [{path: '/',breadcrumbName: formatMessage({ id: 'menu.home' }),},...routers,]}itemRender={(route, params, routes, paths) => {const first = routes.indexOf(route) === 0;return first ? (<Link to={paths.join('/')}>{route.breadcrumbName}</Link>) : (<span>{route.breadcrumbName}</span>);}}footerRender={() => defaultFooterDom}menuDataRender={menuDataRender}rightContentRender={() => <RightContent />}>{children}</ProLayout>);};export default BasicLayout;
If the built-in layout plugin cannot meet your needs, you can tell us through issue and we will deal with it as soon as possible.
You can also turn off the default function through the following configuration.
Set the layout configuration to false.
// config.jsimport { defineConfig } from 'umi';export const config = defineConfig({layout: false,});