React 和 Ant Design(以下简称 AntD)是当前前端开发中非常受欢迎的两个技术栈。本文将介绍如何使用 React 和 AntD 搭建菜单组件并实现一些常用功能。
为什么要使用 AntD
AntD 是一个优秀的 UI 库,它包含了丰富的组件、样式和工具,可以快速搭建一个现代化、美观大气的 web 应用。AntD 遵循响应式设计,支持移动端和桌面端的自适应,并提供了强大的主题定制功能,可以满足不同项目的需求。
菜单组件的需求分析
在很多 web 应用中,菜单是必须的组件之一。它通常包含了网站的主要导航、功能入口等信息。在本次实现的菜单组件中,我们将实现以下功能:
- 通过路由配置自动生成菜单项,并支持嵌套。
- 支持菜单项的展开和收缩,并自动选中当前路由所对应的菜单项。
- 支持菜单项的点击事件,并在页面刷新时自动选中当前路由。
- 支持菜单主题的定制。
路由配置
为了实现自动生成菜单项的功能,我们需要先配置路由。React Router 是一个流行的路由库,它提供了多种路由定义方式,其中最简单的方式是通过 JSON 对象定义。这里我们将使用 JSON 方式来定义路由。
// javascriptcn.com 代码示例 const routes = [ { path: '/home', name: '首页', component: Home, }, { path: '/dashboard', name: '控制台', icon: <DashboardOutlined />, children: [ { path: '/dashboard/analysis', name: '分析页', component: Analysis, }, { path: '/dashboard/monitor', name: '监控页', component: Monitor, }, { path: '/dashboard/workplace', name: '工作台', component: Workplace, }, ], }, { path: '/form', name: '表单页', icon: <FormOutlined />, children: [ { path: '/form/basic', name: '基础表单', component: BasicForm, }, { path: '/form/step', name: '分步表单', component: StepForm, }, { path: '/form/advanced', name: '高级表单', component: AdvancedForm, }, ], }, ... ];
上面的代码中,我们定义了三个顶级路由,分别为 home
、dashboard
和 form
。其中 dashboard
和 form
路由都有对应的子路由,用于支持横向扩展。每个路由对象包含了 path
、name
、component
和 children
等属性。其中 path
和 component
是必须的,name
是用于显示菜单项文本的属性,icon
是用于显示菜单项图标的属性, children
是子路由定义。
菜单组件实现
接下来,我们将使用 AntD 的 Menu
和 Icon
组件来实现菜单项的显示和操作。在 Menu
组件中,我们可以使用 mode
属性来设置菜单的展示模式为 inline
,这样可以将菜单项在垂直方向上排列。selectedKeys
属性可以用于设置当前被选中的菜单项,而 onSelect
属性则用于监听菜单项的选中事件。
在 Menu.Item
组件中,我们可以设置 key
、name
和 icon
属性,这样可以渲染出对应的菜单项。
// javascriptcn.com 代码示例 import React from 'react'; import { Menu } from 'antd'; import { DashboardOutlined, FormOutlined, MenuOutlined, } from '@ant-design/icons'; import { routes } from './routes'; const { SubMenu } = Menu; const AppMenu = ({ location }) => { const [openKeys, setOpenKeys] = React.useState([]); const rootSubmenuKeys = routes.filter((r) => r.children).map((r) => r.path); const handleMenuOpenChange = (keys) => { const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1); if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) { setOpenKeys(keys); } else { setOpenKeys(latestOpenKey ? [latestOpenKey] : []); } }; return ( <Menu theme="dark" mode="inline" selectedKeys={[location.pathname]} openKeys={openKeys} onOpenChange={handleMenuOpenChange} > {routes.map(({ path, name, icon, children }) => { if (children) { return ( <SubMenu key={path} icon={icon} title={name}> {children.map((route) => ( <Menu.Item key={route.path}>{route.name}</Menu.Item> ))} </SubMenu> ); } return ( <Menu.Item key={path} icon={icon}> {name} </Menu.Item> ); })} </Menu> ); }; export default AppMenu;
在上面的代码中,我们使用了 React 的 useState
钩子来维护菜单项的展开状态。rootSubmenuKeys
变量用于记录有子路由的菜单项的 path
属性,以便在展开和收缩菜单项时进行判断。handleMenuOpenChange
函数用于监听菜单项的展开和收缩事件,以便于更新菜单项的展开状态。在 Menu.SubMenu
组件中,我们使用了 title
属性来显示菜单项的名称,而在 Menu.Item
组件中,我们直接渲染了菜单项的名称。
菜单组件应用
一旦实现了菜单组件,我们就可以在页面中进行应用了。在下面的示例代码中,我们将 AppMenu
组件作为侧边栏组件来使用,这样就可以在左侧显示出我们实现的菜单项。同时,我们还引入了 react-router-dom
库中的 Switch
和 Route
组件,这样就可以在右侧显示出选中的路由所对应的组件。
// javascriptcn.com 代码示例 import React from 'react'; import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'; import { Layout } from 'antd'; import AppMenu from './AppMenu'; import { routes } from './routes'; import './App.css'; const { Header, Content } = Layout; const App = () => { return ( <Router> <Layout> <Header className="header"> <div className="logo" /> <MenuOutlined /> </Header> <Layout> <AppMenu /> <Layout className="site-layout"> <Content style={{ margin: '24px 16px 0' }}> <div className="site-layout-background" style={{ padding: 24 }}> <Switch> {routes.map((route) => ( <Route key={route.path} path={route.path} exact={route.exact} component={route.component} /> ))} </Switch> </div> </Content> </Layout> </Layout> </Layout> </Router> ); }; export default App;
在上面的代码中,我们使用了 AntD 的 Layout
组件,其中 Header
组件用于显示顶部栏,Content
组件用于显示选中路由所对应的组件,而 Layout
组件则用于布局侧边栏和内容部分。Switch
和 Route
组件可以在路由匹配时动态创建对应的组件实例,从而实现页面的动态切换。
主题定制
AntD 提供了多种主题定制方式,最简单的方式是通过修改 less 变量来实现。在项目中引入 less-loader
后,可以通过在 theme.less
文件中定义 AntD 的 less 变量来修改主题。
例如,要将菜单项背景颜色改为蓝色,可以在 theme.less
文件中添加如下代码:
@menu-bg: #1890ff;
修改完毕后,需要重新编译项目才能生效。
总结
本文介绍了如何使用 React 和 AntD 来实现一个菜单组件,并支持嵌套、展开和收缩、路由匹配和定制主题等功能。菜单组件是一个常用的 UI 组件,掌握这些技能可以让我们在项目开发中更加高效地构建出美观、实用、易用的 web 应用。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653dc0327d4982a6eb774225