如何基于数据动态渲染Ant Design的<SubMenu>与<Menu.Item>做属性展示?
动态渲染可行性
完全可以实现,本质是对数据源做两层遍历,外层遍历生成<SubMenu>,内层遍历生成<Menu.Item>即可,具体实现步骤如下:
- 先约定传入的数据源格式,保证每一项包含
Name字段,其余为要展示的属性:
const demoData = [ { Name: '苹果', 颜色: '红色', 类型: '水果', 口味: '甜' }, { Name: '黄瓜', 颜色: '绿色', 类型: '蔬菜', 口味: '清爽' } ]
- 组件实现代码:
import { Menu } from 'antd'; import { AppstoreOutlined } from '@ant-design/icons'; const AttrShowMenu = ({ dataSource }) => { return ( <Menu mode="inline" // 可选配置:默认展开所有SubMenu defaultOpenKeys={dataSource.map(item => item.Name)} > {dataSource.map(item => { // 解构提取SubMenu标题,剩下的属性为子项内容 const { Name, ...attrList } = item; return ( <Menu.SubMenu key={Name} icon={<AppstoreOutlined />} title={Name} > {Object.entries(attrList).map(([attrKey, attrValue]) => ( <Menu.Item key={`${Name}-${attrKey}`}> {attrKey}:{attrValue} </Menu.Item> ))} </Menu.SubMenu> ) })} </Menu> ) } // 调用时直接传入数据源即可 // <AttrShowMenu dataSource={demoData} />
注意事项
- 需保证每条数据的
Name字段唯一,子项key使用Name+属性名组合,避免重复key导致的渲染异常 - 若属性值为对象、数组等复杂类型,可自行添加格式化逻辑,比如数组转为逗号分隔字符串后再展示
替代实现方案
如果不需要Menu组件的导航相关能力,更推荐用更匹配纯展示场景的组件:
- Collapse 折叠面板:天生就是「标题+展开内容」的结构,没有Menu自带的选中高亮、路由跳转等冗余逻辑,动态渲染逻辑和上述方案完全一致,更适合纯属性展示场景,示例代码:
import { Collapse } from 'antd'; const AttrShowCollapse = ({ dataSource }) => { const collapseItems = dataSource.map(item => { const { Name, ...attrList } = item; return { key: Name, label: Name, children: Object.entries(attrList).map(([k, v]) => ( <div key={k} style={{ padding: '4px 0' }}>{k}:{v}</div> )) } }) return <Collapse defaultActiveKey={dataSource.map(i => i.Name)} items={collapseItems} /> }
- Descriptions 描述列表:如果不需要折叠交互,要平铺展示所有属性,Descriptions组件自带的表格式布局会让属性展示更规整,也支持按对象分组展示
- Tree 树形组件:如果后续需要支持多级嵌套的属性结构,Tree组件的适配性更高,只需调整数据源结构即可支持多层级展示,不需要修改太多渲染逻辑
内容的提问来源于stack exchange,提问作者user15724342
相关产品推荐
相关产品推荐

