React + antd (Menu组件渲染多级菜单)
菜单数据结构
[ { "title": "首页", "icon": null, "path": "/home", "children": [] }, { "title": "Option", "icon": null, "path": "/home", "children": [ { "title": "Option 1", "icon": null, "path": "/home", "children": [] }, { "title": "Option 2", "icon": null, "path": "/home", "children": [ { "title": "Option 3", "icon": null, "path": "/home", "children": [] } ] } ] } ]
实现代码
import React, { useState, useEffect } from "react";
import { Menu } from 'antd';
import { MenuWrapper } from './styled'
import logoIcon from '@/assets/img/logo.svg'
import { getMenuList } from '@/api/menu'
const { SubMenu } = Menu;
interface IMenu {
title: string;
children: Array;
path: string;
icon?: string;
}
const MenuComps: React.FC = () => {
const [menuData, setMenuData] = useState>([])
const handleClick = (e: any) => {
console.log('click ', e);
}
// 获取菜单数据
const getMenuData = async () => {
const res = await getMenuList()
setMenuData(res.data)
}
useEffect(() => {
getMenuData()
}, [])
// 渲染不含children的目录
const renderNoChildMenu = (item: IMenu) => {
return { item.title }
}
// 渲染含有children的目录
const renderChildMenu = (item: IMenu) => {
return
{
item.children.map((child) => {
return renderMenu(child)
})
}
}
// 渲染菜单
const renderMenu = (item: IMenu) => {
return item.children.length ? renderChildMenu(item) : renderNoChildMenu(item)
}
return (
"menu-wrapper">
"menu-header">
"" />
React Demo
<Menu
onClick={handleClick}
style={{ width: '100%', marginTop: '2px' }}
defaultSelectedKeys={['1']}
defaultOpenKeys={[]}
mode="inline"
>
{/*
Option 1
Option 2
Option 3
Option 4
Option 12 */}
{ menuData.map((item: any) => renderMenu(item)) }
)
}
export default MenuComps
展示效果