说明:antd-pro的侧边导航栏带有自动缩放、移动端适配的功能,去看了antd-pro的文档,发现是用了一个layout pro组件,这个组件封装还是比较强大了,今天我就用hooks对照着功能写一个一模一样。
效果图:
使用antd4.x
侧边栏组件:
import React, { Fragment } from 'react'
import { Menu, Drawer, Layout } from 'antd'
import {
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from '@ant-design/icons';
import { Link } from 'dva/router';
import style from './index.css'
import PropTypes from 'prop-types'
const { Sider } = Layout;
const NavContent = () => {
return (
<Fragment>
<div className={style.logo} />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
<Menu.Item key="1" icon={<UserOutlined />}>
<Link to="/admin/index">
Index
</Link>
</Menu.Item>
<Menu.Item key="2" icon={<VideoCameraOutlined />}>
<Link to="/admin/tables">
Tables
</Link>
</Menu.Item>
<Menu.Item key="3" icon={<UploadOutlined />}>
nav 3
</Menu.Item>
</Menu>
</Fragment>
)
}
const Nav = ({ isMobile, collapsed, changeCollapsed, width = 256 }) => {
return (
<Fragment>
{
!isMobile ? <Sider
collapsible
trigger={null}
collapsed={collapsed}
width={width}
style={{
height: '100vh',
}}
onBreakpoint={broken => {
changeCollapsed(broken)
}}
breakpoint="xl"
>
<NavContent />
</Sider> :
<Drawer
placement='left'
onClose={() => {
changeCollapsed(!0)
}}
visible={!collapsed}
closable={false}
bodyStyle={{
height: '100vh',
padding: 0
}}
>
<Sider
width={width}
style={{
height: '100vh',
}}
>
<NavContent />
</Sider>
</Drawer>
}
</Fragment>
)
}
Nav.propTypes = {
isMobile: PropTypes.bool.isRequired,
collapsed: PropTypes.bool.isRequired,
changeCollapsed: PropTypes.func.isRequired,
width: PropTypes.number
}
export default Nav
复制代码
参数 | 说明 |
---|---|
"isMobile" | 是否为移动端 |
"collapsed" | 是否折叠 |
"changeCollapsed" | func 改变折叠状态的回调 |
"width" | 侧边栏展示的宽度 |
如果是移动端的话,则展示抽屉+侧边栏内容,如果页面大小太闲则折叠导航条,功能和antd-pro一致
使用方法:(hooks)
import React, { useState, useEffect } from 'react'
import { Layout } from 'antd';
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
} from '@ant-design/icons';
import style from './index.css'
import Index from '../../routes/Index'
import Tables from '../../routes/Tables'
import { Route } from 'dva/router';
import Nav from '../../components/Nav'
const { Header, Content } = Layout;
const Admin = () => {
const [collapsed, setCollapsed] = useState(false)
const [isMobile, setIsMobile] = useState(false)
const handleResize = () => {
document.documentElement.clientWidth < 768
? setIsMobile(true)
: setIsMobile(false)
}
useEffect(() => {
handleResize()
window.onresize = handleResize
return () => {
window.onresize = null
}
}, [])
return (
<Layout>
<Nav
collapsed={collapsed}
isMobile={isMobile}
changeCollapsed={(broken) => setCollapsed(broken)}
/>
<Layout className="site-layout">
<Header style={{ padding: 0, backgroundColor: '#ffffff' }}>
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
className: style.trigger,
onClick: () => {
setCollapsed(!collapsed)
},
})}
</Header>
<Content
style={{
margin: '24px 16px',
padding: 24,
minHeight: 280,
backgroundColor: '#ffffff'
}}
>
<Route path="/admin/index" component={Index} />
<Route path="/admin/tables" component={Tables} />
</Content>
</Layout>
</Layout>
)
}
export default Admin
复制代码
使用的时候用effect监听一个页面窗口来改变状态,并把所需要的参数都传递给nav就行了
打完收工~