最近在写一个react demo 其中有个场景需求是 实现 导航菜单 路径匹配时选中项高亮 存在 打开子菜单项时 页面刷新 保持打开状态栏
代码实现颇有意思 记录一下
技术栈为 react-router-dom v6 版本 和 antd v5 版本
菜单项 主页
javascript
import "./index.less";
import logo from "../../asstes/images/logo.png";
import {Link, useLocation, useNavigate} from "react-router-dom";
import { Menu } from "antd";
// 引入菜单配置项
import menuList from "../../config/menuConfig";
/*左侧导航组件
*/
/*左侧导航组件*/
function LeftNav() {
// 引入子菜单
const SubMenu = Menu.SubMenu;
// 菜单栏跳转
const navigate = useNavigate()
const menuClick = (route) =>{
// console.log(route)
navigate(route.key)
}
// 获取当前页面路径
const currentPath = useLocation()
// 定一个函数来判断当前选中的路由是否需要打开,前提是有子路由 keys 组件数组
const getOpenKey = (url_key,keys) => {
let openKey = ''
keys.forEach(item => {
if(item.children){
// 存在子路由
item.children.forEach(
subItem =>{
if(url_key === subItem.key){
// 传入索引等于子路由索引 存储子路由索引
openKey = item.key
}
// 因为有嵌套列表所以需要采用递归调用
if(subItem.children){
getOpenKey(item.children)
}
}
)
}
})
// 返回存储的索引
return openKey
}
// 渲染菜单项
const menuNodes = (
<Menu
mode="inline"
theme="dark"
defaultSelectedKeys={["1"]}
items={menuList}
style={{ height: "100%", borderRight: 0 }}
onClick={menuClick}
selectedKeys={[currentPath.pathname]}
defaultOpenKeys={[getOpenKey(currentPath.pathname,menuList)]}
/>
);
return (
<div className="left-nav">
<Link to={"/"} className="left-nav-header">
<img src={logo} alt="logo" />
<h3>云端后台</h3>
</Link>
{menuNodes}
</div>
);
}
export default LeftNav;
菜单数组
javascript
import {
AppstoreOutlined, AreaChartOutlined, BarChartOutlined,
BarsOutlined,
HomeOutlined, LineChartOutlined, PieChartOutlined,
SafetyOutlined,
ToolOutlined,
UserOutlined
} from "@ant-design/icons";
const menuList = [
{
label: "首页", // 菜单标题名称
key: "/home", // 对应的 path
icon: <HomeOutlined />, // 图标名称
},
{
label: "商品",
key: "/products",
icon: <AppstoreOutlined />,
children: [
// 子菜单列表
{
label: "品类管理",
key: "/category",
icon: <BarsOutlined />,
},
{
label: "商品管理",
key: "/product",
icon: <ToolOutlined />,
},
],
},
{
label: "用户管理",
key: "/user",
icon: <UserOutlined />,
},
{
label: "角色管理",
key: "/role",
icon: <SafetyOutlined />,
},
{
label: "图形图表",
key: "/charts",
icon: <AreaChartOutlined />,
children: [
{
label: "柱形图",
key: "/charts/bar",
icon: <BarChartOutlined />,
},
{
label: "折线图",
key: "/charts/line",
icon: <LineChartOutlined />,
},
{
label: "饼图",
key: "/charts/pie",
icon: <PieChartOutlined />,
},
],
},
];
export default menuList;
getOpenKey 通过传入当前路径索引 和 dom数组 遍历dom数组 存在子路由时 进行判断 数据源 当传入索引等于子路由索引 时 存入此时 打开的索引 openKey
最终返回 openKey 再赋值给 menu的 defaultOpenKeys 属性 保持页面打开时 仍存储打开栏状态