Ant Design的Menu菜单怎么设置选中项后不自动展开子菜单?
我在用Ant Design的侧边栏菜单时遇到个奇怪的问题。设置了mode为inline,点击父菜单项展开子菜单后,如果直接点击父菜单的选中项,整个子菜单会突然收起来,这让我很困扰。
我尝试过设置defaultOpenKeys和selectedKeys,但发现只要再次点击已选中的父菜单项,子菜单就会自动折叠。有没有办法让选中项保持展开状态呢?
<template>
<a-menu mode="inline" :selected-keys="[currentKey]" :default-open-keys="['sub1']">
<a-menu-item key="home">
首页
</a-menu-item>
<a-sub-menu key="sub1">
<template #title>内容管理</template>
<a-menu-item key="article">文章列表</a-menu-item>
<a-menu-item key="category">分类管理</a-menu-item>
</a-sub-menu>
</a-menu>
</template>
现在的情况是,当点击”内容管理”展开子菜单后,如果再次点击”内容管理”这个父菜单项,子菜单就会收起来。但用户可能只是想保持当前选中状态,而不是折叠菜单…
selected-keys。解决办法有俩:
第一个是直接用
open-keys(不是default-open-keys)配合@open-change手动控制展开状态,这样你就能在点击父菜单时判断:如果是已选中项,就别让它收起来。比如你可以在 data 里定义
openKeys: ['sub1'],然后在a-menu上绑定:open-keys="openKeys",再加个@open-change="handleOpenChange":然后模板里改成:
这样用户反复点「内容管理」,子菜单就不会收了。
第二个更偷懒的方案(适合懒人):直接在父菜单项上加个
@click.stop阻断点击冒泡,这样点击它就不会触发展开收起逻辑了:不过这个方案要小心——如果后续你还想在「点击父菜单标题」时做别的事(比如跳转到某个默认页),那可能不太合适。
我一般用第一种,可控性高点。主题里加几行逻辑就行,别被它默认行为带跑偏了。
openKeys来手动管理子菜单的展开状态,而不是依赖组件的默认行为。性能上,我们尽量避免频繁的状态更新,所以可以用一个变量来记录当前展开的子菜单,只在必要时更新。
具体做法是去掉
defaultOpenKeys,改用受控属性openKeys,并在点击事件中判断是否需要保持展开状态。下面是修改后的代码:这里的核心是
@open-change事件和openKeys属性的配合。handleOpenChange方法会在用户操作菜单时触发,如果返回的keys是空数组(表示要折叠),我们就保留原来的openKeys,从而避免子菜单被意外收起。这样处理后,用户点击父菜单项时,子菜单不会自动折叠,性能上也避免了不必要的 DOM 操作。如果还有其他需求,比如动态加载子菜单,也可以在这个基础上扩展。