React新手求助:如何用NavLink在Material UI导航栏实现三级子菜单
实现React三级导航子菜单(Report > My report > MIS report)
嘿,作为React新手,要实现三级嵌套子菜单其实不难,咱们一步步来搞定它!结合你用的react-router-dom和Material-UI组件,我给你整理了具体的实现方案:
1. 重构mainListItems为带状态的函数组件
原来的mainListItems是静态JSX,咱们需要把它改成能控制菜单展开/收起的函数组件,用React Hooks来管理状态。首先确保你已经安装了Material-UI的折叠组件(如果没装,执行npm install @mui/material @mui/icons-material即可)。
import React, { useState } from 'react'; import { List, ListItem, ListItemIcon, ListItemText, Collapse } from '@mui/material'; import { NavLink } from 'react-router-dom'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; export const MainListItems = () => { // 控制一级菜单(Report)的展开状态 const [isReportOpen, setIsReportOpen] = useState(false); // 控制二级菜单(My report)的展开状态 const [isMyReportOpen, setIsMyReportOpen] = useState(false); const toggleReportMenu = () => { setIsReportOpen(!isReportOpen); }; const toggleMyReportMenu = () => { setIsMyReportOpen(!isMyReportOpen); }; return ( <List> <NavLink to="/dashboard" style={{ textDecoration: 'none', color: 'inherit' }}> <ListItem button> <ListItemIcon></ListItemIcon> <ListItemText primary="Dashboard" /> </ListItem> </NavLink> <NavLink to="/userform" style={{ textDecoration: 'none', color: 'inherit' }}> <ListItem button> <ListItemIcon></ListItemIcon> <ListItemText primary="Registration" /> </ListItem> </NavLink> {/* 一级菜单:Report */} <ListItem button onClick={toggleReportMenu}> <ListItemIcon></ListItemIcon> <ListItemText primary="Report" /> {isReportOpen ? <ExpandMoreIcon /> : <ChevronRightIcon />} </ListItem> <Collapse in={isReportOpen} timeout="auto" unmountOnExit> <List component="div" disablePadding> {/* 二级菜单:My report */} <ListItem button onClick={toggleMyReportMenu} sx={{ pl: 4 }}> <ListItemIcon></ListItemIcon> <ListItemText primary="My report" /> {isMyReportOpen ? <ExpandMoreIcon /> : <ChevronRightIcon />} </ListItem> <Collapse in={isMyReportOpen} timeout="auto" unmountOnExit> <List component="div" disablePadding> {/* 三级菜单:MIS report */} <NavLink to="/report/my-report/mis-report" style={{ textDecoration: 'none', color: 'inherit' }}> <ListItem button sx={{ pl: 8 }}> <ListItemIcon></ListItemIcon> <ListItemText primary="MIS report" /> </ListItem> </NavLink> </List> </Collapse> </List> </Collapse> </List> ); };
2. 更新路由配置(App.js)
接下来要给三级菜单对应的路径添加路由,记得先创建好MISReport组件(你可以根据业务需求编写这个组件的内容):
import React from 'react'; import { HashRouter, Switch, Route, Redirect } from 'react-router-dom'; import SignIn from './SignIn'; // 你的组件路径 import UserForm from './UserForm'; import Dashboard from './Dashboard'; import MISReport from './MISReport'; // 新增的MIS报告组件 const App = () => ( <HashRouter> <Switch> <Route path="/signin" component={SignIn} /> <Route path="/userform" component={UserForm} /> <Route path="/dashboard" component={Dashboard} /> {/* 新增三级菜单对应的路由 */} <Route path="/report/my-report/mis-report" component={MISReport} /> <Redirect from="/" to="/signin" /> </Switch> </HashRouter> ); export default App;
3. 关键细节说明
- 层级样式:用
sx={{ pl: 4 }}和sx={{ pl: 8 }}给子菜单添加缩进,让层级关系更直观;给NavLink添加样式是为了去掉默认链接样式,保持菜单视觉统一。 - 展开/收起逻辑:通过两个
useState变量分别控制一、二级菜单的展开状态,点击菜单时触发状态切换。 - 路由匹配:确保
NavLink的to属性和路由配置的path完全对应,这样点击菜单才能正确跳转至目标页面。
这样你就能实现一个可展开收起的三级子菜单啦,测试一下:点击Report会展开My report,再点击My report就能看到MIS report,点击MIS report会跳转到对应的页面~
内容的提问来源于stack exchange,提问作者sandeep pradhan
相关产品推荐
相关产品推荐

