-
-
Notifications
You must be signed in to change notification settings - Fork 53.7k
Labels
Description
What problem does this feature solve?
当前的 Menu.Item
组件虽然可以通过 children
或 label
属性自定义其内部显示的内容,但无法自定义 Menu.Item
的根节点(通常是 <li>
元素)或在其外部包裹一层自定义的 DOM/组件。
在一些复杂的业务场景中,我们有强烈的需求去包裹 Menu.Item
,例如:
- 路由链接集成:希望使用
react-router
的<Link>
组件包裹整个Menu.Item
,使得整个菜单项区域都成为可点击的热区,而不仅仅是内部的<a>
标签。 - 集成功能性组件:需要将菜单项包裹在
<Upload>
、<Tooltip>
或其他功能性组件中,以实现点击菜单项触发文件上传或显示复杂的提示信息等交互。 - 解决特定布局与样式问题:如下方场景所述,当需要对菜单项做特殊布局(如
position: sticky
)时,直接对<li>
元素设置样式会引发渲染问题(如背景色穿透),如果能在外部包裹一个<div>
来处理布局和背景色,则可以完美解决此类问题。

What does the proposed API look like?
我希望 Menu.Item
支持一个类似 antd Table
column.render
的 API,允许开发者接收原始的菜单项节点,并返回一个自定义的 ReactNode。这给予了开发者完全的渲染控制权。
建议在 Menu
的 items
API 或 Menu.Item
组件上增加一个 render
属性。
API 提议: 在 items
属性中支持 render
<Menu
items={[
{
key: 'mail',
label: 'Navigation One',
icon: <MailOutlined />,
},
{
key: 'app',
label: 'Navigation Two',
icon: <AppstoreOutlined />,
// render 方法接收默认渲染的节点作为参数,允许开发者对其进行包裹或替换
render: (originNode, item) => {
// 场景1: 包裹 Link
return <Link to="/app">{originNode}</Link>;
}
},
{
key: 'upload',
label: 'Upload File',
// 场景2: 包裹 Upload 组件
render: (originNode) => {
return <Upload>{originNode}</Upload>;
}
},
{
key: 'plugin-store',
label: '插件商店',
// 场景3: 解决 sticky 布局的样式问题
render: (originNode) => {
// 在外部 div 上实现 sticky, 在 originNode (li) 上保留 hover 效果
// 这样就避免了 hover 背景穿透的问题
return <div style={{ position: 'sticky', bottom: 0 }}>{originNode}</div>
}
}
]}
/>
下图展示了我希望实现的 "插件商店" 菜单项 sticky
在底部的效果。直接在 <li>
上实现 sticky
会导致滚动时,<li>
的 hover 背景色会穿透到上方的其他菜单项,
而通过 render
方法包裹一层 <div>
来应用 sticky
样式则可以完美解决此问题。
期望实现的效果:
通过引入 render
API,Menu
组件的灵活性和可组合性将得到极大的提升,能够更好地适应现代前端应用中日益复杂的业务场景。
dosubotnouman2075