需求:要求对于拥有children的菜单,点击一级菜单的label可以跳转到一级菜单对应的路由,点击一级菜单右侧的箭头才展开二级菜单。
原代码:
import { Menu, MenuProps, Space, Typography } from 'antd';
import React, { useState } from 'react'
import { menuItems } from '@/config/menuConfig'
import { useRouter } from 'next/navigation'
import Icon from '@/components/Icons';
export default function CustomMenu() {
const { SubMenu, Item } = Menu
const { Text } = Typography
const router = useRouter()
const [selectedKeys,setSelectedKeys]=useState(['/'])
// 获取当前点击的菜单项及其父级菜单
const getParentKey = (key: any) => {
for (const item of menuItems) {
if (item.children) {
const found = item.children.find(child => child.key === key)
if (found) {
return item.key
}
}
}
return null
}
const handleMenuItemClick: MenuProps['onClick'] = ({ key }) => {
const parentKey = getParentKey(key)
let fullPath = key
if (parentKey) {
fullPath = `${parentKey}/${key}`
}
setSelectedKeys([key])
router.push(fullPath)
}
return (
<Menu
onClick={handleMenuItemClick}
mode="horizontal"
defaultSelectedKeys={['/']}
triggerSubMenuAction="click"
selectedKeys={selectedKeys}
>
{menuItems.map((item) =>
item.children ? (
<SubMenu
key={item.key}
title={
<Space>
<Text
onClick={(e)=>{
e.stopPropagation();
setSelectedKeys([item.key])
router.push(item.key)
}}
>
{item.label}
</Text>
<Icon type='DownOutlined'/>
</Space>
}
>
{item.children.map((subItem) => (
<Item key={subItem.key}>{subItem.label}</Item>
))}
</SubMenu>
) : (
<Item key={item.key}>{item.label}</Item>
)
)}
</Menu>
)
}
以上代码可是实现功能,但是会报错:
解决办法:对submenu进行改造
import { Menu, MenuProps, Space, Typography } from 'antd';
import React, { useState } from 'react'
import { menuItems } from '@/config/menuConfig'
import { useRouter } from 'next/navigation'
import Icon from '@/components/Icons';
export default function CustomMenu() {
const { Text } = Typography
const router = useRouter()
const [selectedKeys,setSelectedKeys]=useState(['/'])
// 获取当前点击的菜单项及其父级菜单
const getParentKey = (key: any) => {
for (const item of menuItems) {
if (item.children) {
const found = item.children.find(child => child.key === key)
if (found) {
return item.key
}
}
}
return null
}
const handleMenuItemClick: MenuProps['onClick'] = ({ key }) => {
const parentKey = getParentKey(key)
let fullPath = key
if (parentKey) {
fullPath = `${parentKey}/${key}`
}
setSelectedKeys([key])
router.push(fullPath)
}
const generateMenuItems = () => {
return menuItems.map((item) => {
if (item.children) {
return {
key: item.key,
label: (
<Space>
<Text onClick={(e) => {
e.stopPropagation();
setSelectedKeys([item.key]);
router.push(item.key);
}}>
{item.label}
</Text>
<Icon type="DownOutlined" />
</Space>
),
children: item.children.map((subItem) => ({
key: subItem.key,
label: subItem.label,
})),
};
} else {
return {
key: item.key,
label: item.label,
};
}
});
};
return (
<Menu
onClick={handleMenuItemClick}
mode="horizontal"
defaultSelectedKeys={['/']}
triggerSubMenuAction="click"
selectedKeys={selectedKeys}
items={generateMenuItems()}
/ >
)
}