| | |
| | | import React, { useState } from 'react'; |
| | | import { |
| | | MenuFoldOutlined, |
| | | MenuUnfoldOutlined, |
| | | UploadOutlined, |
| | | UserOutlined, |
| | | VideoCameraOutlined, |
| | | LogoutOutlined, |
| | | SearchOutlined, |
| | | } from '@ant-design/icons'; |
| | | import { Layout, Menu, Button, theme } from 'antd'; |
| | | import { |
| | | PageContainer, |
| | | ProCard, |
| | | ProConfigProvider, |
| | | ProLayout, |
| | | SettingDrawer, |
| | | } from '@ant-design/pro-components'; |
| | | import { |
| | | Button, |
| | | ConfigProvider, |
| | | Dropdown, |
| | | Input, |
| | | theme, |
| | | } from 'antd'; |
| | | import React, { useState } from 'react'; |
| | | import defaultProps from './_defaultProps'; |
| | | import logo from '@/assets/logo.png'; |
| | | |
| | | const { Header, Sider, Content } = Layout; |
| | | |
| | | const App = () => { |
| | | const [collapsed, setCollapsed] = useState(false); |
| | | const { |
| | | token: { colorBgContainer, borderRadiusLG }, |
| | | } = theme.useToken(); |
| | | |
| | | const SearchInput = () => { |
| | | const { token } = theme.useToken(); |
| | | return ( |
| | | <Layout style={{ height: '100vh' }}> |
| | | <Sider trigger={null} collapsible collapsed={collapsed}> |
| | | <div className="demo-logo-vertical" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}> |
| | | <img src={logo} alt="Logo" style={{ maxWidth: '80%', height: 'auto' }} /> |
| | | </div> |
| | | <Menu |
| | | theme="dark" |
| | | mode="inline" |
| | | defaultSelectedKeys={['1']} |
| | | items={[ |
| | | { |
| | | key: '1', |
| | | icon: <UserOutlined />, |
| | | label: 'nav 1', |
| | | }, |
| | | { |
| | | key: '2', |
| | | icon: <VideoCameraOutlined />, |
| | | label: 'nav 2', |
| | | }, |
| | | { |
| | | key: '3', |
| | | icon: <UploadOutlined />, |
| | | label: 'nav 3', |
| | | }, |
| | | ]} |
| | | /> |
| | | </Sider> |
| | | <Layout> |
| | | <Header |
| | | style={{ |
| | | padding: 0, |
| | | background: colorBgContainer, |
| | | }} |
| | | > |
| | | <Button |
| | | type="text" |
| | | icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />} |
| | | onClick={() => setCollapsed(!collapsed)} |
| | | <div |
| | | key="SearchOutlined" |
| | | aria-hidden |
| | | style={{ |
| | | display: 'flex', |
| | | alignItems: 'center', |
| | | marginInlineEnd: 24, |
| | | }} |
| | | onMouseDown={(e) => { |
| | | e.stopPropagation(); |
| | | e.preventDefault(); |
| | | }} |
| | | > |
| | | <Input |
| | | style={{ |
| | | borderRadius: 4, |
| | | marginInlineEnd: 12, |
| | | backgroundColor: token.colorBgTextHover, |
| | | }} |
| | | prefix={ |
| | | <SearchOutlined |
| | | style={{ |
| | | fontSize: '16px', |
| | | width: 64, |
| | | height: 64, |
| | | color: token.colorTextLightSolid, |
| | | }} |
| | | /> |
| | | </Header> |
| | | <Content |
| | | style={{ |
| | | margin: '24px 16px', |
| | | padding: 24, |
| | | minHeight: 280, |
| | | background: colorBgContainer, |
| | | borderRadius: borderRadiusLG, |
| | | }} |
| | | > |
| | | Content |
| | | </Content> |
| | | </Layout> |
| | | </Layout> |
| | | } |
| | | placeholder="搜索方案" |
| | | bordered={false} |
| | | /> |
| | | </div> |
| | | ); |
| | | }; |
| | | export default App; |
| | | |
| | | export default () => { |
| | | const [settings, setSetting] = useState({ |
| | | fixSiderbar: true, |
| | | layout: 'mix', |
| | | splitMenus: true, |
| | | }); |
| | | |
| | | const [pathname, setPathname] = useState('/list/sub-page/sub-sub-page1'); |
| | | const [num, setNum] = useState(40); |
| | | if (typeof document === 'undefined') { |
| | | return <div />; |
| | | } |
| | | return ( |
| | | <div |
| | | id="pro-layout" |
| | | style={{ |
| | | height: '100vh', |
| | | overflow: 'auto', |
| | | }} |
| | | > |
| | | <ProConfigProvider hashed={false}> |
| | | <ConfigProvider |
| | | getTargetContainer={() => { |
| | | return document.getElementById('pro-layout') || document.body; |
| | | }} |
| | | > |
| | | <ProLayout |
| | | prefixCls="my-prefix" |
| | | bgLayoutImgList={[ |
| | | { |
| | | src: 'https://img.alicdn.com/imgextra/i2/O1CN01O4etvp1DvpFLKfuWq_!!6000000000279-2-tps-609-606.png', |
| | | left: 85, |
| | | bottom: 100, |
| | | height: '303px', |
| | | }, |
| | | { |
| | | src: 'https://img.alicdn.com/imgextra/i2/O1CN01O4etvp1DvpFLKfuWq_!!6000000000279-2-tps-609-606.png', |
| | | bottom: -68, |
| | | right: -45, |
| | | height: '303px', |
| | | }, |
| | | { |
| | | src: 'https://img.alicdn.com/imgextra/i3/O1CN018NxReL1shX85Yz6Cx_!!6000000005798-2-tps-884-496.png', |
| | | bottom: 0, |
| | | left: 0, |
| | | width: '331px', |
| | | }, |
| | | ]} |
| | | {...defaultProps} |
| | | location={{ |
| | | pathname, |
| | | }} |
| | | token={{ |
| | | header: { |
| | | colorBgMenuItemSelected: 'rgba(0,0,0,0.04)', |
| | | }, |
| | | }} |
| | | siderMenuType="group" |
| | | menu={{ |
| | | collapsedShowGroupTitle: true, |
| | | }} |
| | | // 个人用户 |
| | | avatarProps={{ |
| | | src: 'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg', |
| | | size: 'small', |
| | | title: '陆晓涛', |
| | | render: (props, dom) => { |
| | | return ( |
| | | <Dropdown |
| | | menu={{ |
| | | items: [ |
| | | { |
| | | key: 'logout', |
| | | icon: <LogoutOutlined />, |
| | | label: '退出登录', |
| | | }, |
| | | ], |
| | | }} |
| | | > |
| | | {dom} |
| | | </Dropdown> |
| | | ); |
| | | }, |
| | | }} |
| | | // 自定义操作列表 |
| | | actionsRender={(props) => { |
| | | if (props.isMobile) return []; |
| | | if (typeof window === 'undefined') return []; |
| | | return [ |
| | | props.layout !== 'side' && document.body.clientWidth > 1400 ? ( |
| | | <SearchInput /> |
| | | ) : undefined, |
| | | ]; |
| | | }} |
| | | // logo信息 |
| | | headerTitleRender={(logo, title, _) => { |
| | | return ( |
| | | <> |
| | | <a> |
| | | {logo} |
| | | {title} |
| | | </a> |
| | | </> |
| | | ); |
| | | }} |
| | | // 在 layout 底部渲染一个块 |
| | | menuFooterRender={(props) => { |
| | | if (props?.collapsed) return undefined; |
| | | return ( |
| | | <div |
| | | style={{ |
| | | textAlign: 'center', |
| | | paddingBlockStart: 12, |
| | | }} |
| | | > |
| | | <div>© 2021 Made with love</div> |
| | | <div>by Ant Design</div> |
| | | </div> |
| | | ); |
| | | }} |
| | | // menu 菜单的头部点击事件 |
| | | onMenuHeaderClick={(e) => console.log(e)} |
| | | // Header 自定义菜单项的 render 方法 |
| | | menuItemRender={(item, dom) => ( |
| | | <div |
| | | onClick={() => { |
| | | setPathname(item.path || '/welcome'); |
| | | }} |
| | | > |
| | | {dom} |
| | | </div> |
| | | )} |
| | | {...settings} |
| | | > |
| | | <PageContainer |
| | | token={{ |
| | | paddingInlinePageContainerContent: num, |
| | | }} |
| | | extra={[ |
| | | <Button key="3">操作</Button>, |
| | | <Button key="2">操作</Button>, |
| | | <Button |
| | | key="1" |
| | | type="primary" |
| | | onClick={() => { |
| | | setNum(num > 0 ? 0 : 40); |
| | | }} |
| | | > |
| | | 主操作 |
| | | </Button>, |
| | | ]} |
| | | subTitle="简单的描述" |
| | | footer={[ |
| | | <Button key="3">重置</Button>, |
| | | <Button key="2" type="primary"> |
| | | 提交 |
| | | </Button>, |
| | | ]} |
| | | > |
| | | <ProCard |
| | | style={{ |
| | | height: '200vh', |
| | | minHeight: 800, |
| | | }} |
| | | > |
| | | <div /> |
| | | </ProCard> |
| | | </PageContainer> |
| | | |
| | | <SettingDrawer |
| | | pathname={pathname} |
| | | enableDarkTheme |
| | | getContainer={(e) => { |
| | | if (typeof window === 'undefined') return e; |
| | | return document.getElementById('pro-layout'); |
| | | }} |
| | | settings={settings} |
| | | onSettingChange={(changeSetting) => { |
| | | setSetting(changeSetting); |
| | | }} |
| | | disableUrlParams={false} |
| | | /> |
| | | </ProLayout> |
| | | </ConfigProvider> |
| | | </ProConfigProvider> |
| | | </div> |
| | | ); |
| | | }; |