Antd中的布局组件
文章目录
- 一、Layout
- 二、Menu
- 三、Grid栅格
布局组件涉及项目框架的搭建,往往被忽略和低关注,毕竟不是经常用到,但是在调整项目结构的时候往往又需要重新设计布局,所以有必要提前归纳分析;
一、Layout
- Layout导出Sider, Content, Header,Sider, Content, Header也只能被Layout包裹,可以写嵌套Layout
- React.createElement语法:const element = createElement(type, props, …children)
import { DesktopOutlined, MailOutlined, MenuFoldOutlined,
MenuUnfoldOutlined, UserOutlined } from '@ant-design/icons';
import { Layout, Menu } from 'antd';
import React, { useState } from 'react';
const { Sider, Content, Header } = Layout;
export default function LayoutPage() {
const [collapsed, setCollapsed] = useState(false);
const items = [
// title:缩进以后,悬浮子菜单;一级菜单不会出现
{ label: '菜单项一', key: 'item-1', title: '菜单项一 悬浮', icon: <MailOutlined /> },
// 菜单项务必填写 key
{
label: '菜单项二',
key: 'item-2',
title: '菜单项二 悬浮',
icon: <MailOutlined />,
children: [{ label: '子菜单项1',
key: 'submenu-item-1', title: '子菜单项1 悬浮' }],
},
{
label: '菜单项3',
key: 'submenu',
children: [
{ label: '子菜单项2', key: 'submenu-item-1' },
{ label: '子菜单项3', key: 'submenu-item-2' },
],
},
];
return (
<div className="Layout">
<Layout>
{/* 左侧菜单 collapsed控制是否缩进菜单 */}
<Sider collapsed={collapsed}>
<div
className="logo"
style={{
height: '64px', display: 'flex', alignItems: 'center',
justifyContent: 'center'
}}
>
<DesktopOutlined style={{ fontSize: '32px', color: 'white' }} />
</div>
<Menu
// theme="dark"
items={items}
mode="inline"
></Menu>
</Sider>
<Layout>
<Header style={{ display: 'flex', justifyContent: 'space-between' }}>
{React.createElement(collapsed ? MenuUnfoldOutlined :
MenuFoldOutlined,
{
className: 'trigger',
style: { color: 'white' },
onClick: () => setCollapsed(!collapsed),
})}
<UserOutlined style={{ color: 'white' }} />
</Header>
<Content>Content</Content>
</Layout>
</Layout>
</div>
);
}
二、Menu
- 菜单栏一般为树型结构,可以点收起菜单栏
- 设置只展开一个一级菜单,子菜单单选
import { DesktopOutlined, MailOutlined, MenuFoldOutlined,
MenuUnfoldOutlined, UserOutlined } from '@ant-design/icons';
import { Layout, Menu } from 'antd';
import React, { useState } from 'react';
const { Sider, Content, Header } = Layout;
export default function LayoutPage() {
const [collapsed, setCollapsed] = useState(false);
const [selectedKeys, setSelectedKeys] = useState([]); // 当前选中的子菜单项
const [openKeys, setOpenKeys] = useState([]); // 当前展开的一级菜单项
const items = [
// title:缩进以后,悬浮子菜单名;一级菜单不会出现
{ label: '菜单项一', key: 'item-1', title: '菜单项一 悬浮',
icon: <MailOutlined /> }, // 菜单项务必填写 key
{
label: '菜单项二',
key: 'item-2',
title: '菜单项二 悬浮',
icon: <MailOutlined />,
children: [{ label: '子菜单项1', key: 'submenu-item-1', title: '子菜单项1 悬浮' }],
},
{
label: '菜单项3',
key: 'submenu',
children: [
{ label: '子菜单项2', key: 'submenu-item-1' },
{ label: '子菜单项3', key: 'submenu-item-2' },
],
},
];
// 一级菜单的key
const openKeysArray = items.map((item) => item.key);
const onOpenChange = (keys) => {
console.log('onOpenChange', keys);
// 找到最新打开的那个菜单项
const latestOpenKey = keys.find((key) => !openKeys.includes(key));
// 只允许出现一个展开的一级菜单
if (openKeysArray.includes(latestOpenKey)) {
setOpenKeys([latestOpenKey]);
} else {
// latestOpenKey不存在,说明关闭最后一个展开菜单
setOpenKeys(latestOpenKey ? [latestOpenKey] : []);
}
};
return (
<div className="Layout">
{/* <h1>Layout</h1> */}
<Layout>
<Sider trigger={null} collapsible collapsed={collapsed}>
<div
className="logo"
style={{ height: '64px', display: 'flex',
alignItems: 'center', justifyContent: 'center' }}
>
<DesktopOutlined style={{ fontSize: '32px', color: 'white' }} />
</div>
<Menu
items={items}
// mode="inline" 一级菜单竖着排列,子菜单隐藏;
// mode="vertical" 一级菜单竖着排列,子菜单隐藏横着排列,hover时子菜单展开;
// mode="horizontal"一级菜单横着排列,hover时子菜单竖着展开;
mode="inline"
openKeys={openKeys}
onOpenChange={onOpenChange}
selectedKeys={selectedKeys}
onClick={(e) => setSelectedKeys([e.key])}
></Menu>
</Sider>
<Layout>
<Header style={{ display: 'flex', justifyContent: 'space-between' }}>
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
{
className: 'trigger',
style: { color: 'white' },
onClick: () => setCollapsed(!collapsed),
})}
<UserOutlined style={{ color: 'white' }} />
</Header>
<Content>Content: {selectedKeys.join('-')}</Content>
</Layout>
</Layout>
</div>
);
}
三、Grid栅格
24等分Grid栅格,Row表示一行,Col表示一列
import { Col, Divider, Row } from 'antd';
export default function GridPage() {
return (
<div className="grid-page">
{/* gutter={[number, number]} [水平间隔, 垂直间隔] */}
{/* 注意水平间隔是左右均分模式,number === 16 代表 padding: 0 8px */}
{/* 垂直间隔在该行下面 16px; 最后一行除外 */}
{/* align类似于 flex中的align-items属性; top | middle | bottom */}
{/* justify类似于 flex中的justify-content属性;
多了一个space-evenly,在space-between基础上即均分剩余空间 */}
{/* 注意考虑多行情况,每个item高度不定,align如何设置 */}
{/* 注意考虑多列情况,有一行排不满,justify如何设置 */}
<Row gutter={[16, 16]} align="top" justify="space-evenly">
<Col span={12}>Col1</Col>
<Col span={6}>Col2</Col>
<Col span={6}>Col3</Col>
<Col span={6}>Col3</Col>
<Col span={6}>Col3</Col>
</Row>
<Divider orientation="left">Horizontal</Divider>
{/* gutter={number} 水平间隔 */}
{/* wrap={boolean} 是否换行 */}
<Row
gutter={{
xl: 16, // xl 1200px 以上,不同的宽度下的独立设置
}}
wrap={true}
>
{/* Col span={number} 占比 */}
{/* offset={number} 左侧偏移, 占据空间但不显示 */}
{/* order={number} 排序,越小越靠前,默认0,其中一个写了order,其他不写容易乱 */}
{/* pull={number} 左侧偏移, 偏移类似于transform, 本体占据空间 */}
{/* push={number} 右侧偏移, */}
<Col span={12} order={2}>
Col1
</Col>
{/* pull push 同时设置时,只显示push */}
<Col span={6} order={1} offset={6} pull={6} push={1}>
Col2
</Col>
<Col span={6} order={3}>
Col3
</Col>
{/* xl 1200px 以上,不同的宽度下的独立设置 */}
<Col span={6} order={4} xl={{ span: 12, offset: 6 }}>
Col4
</Col>
</Row>
</div>
);
}