一鸣则以 發表於 2026-1-6 09:23:53

Element Plus 菜单组件区别和用法最佳实践

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">组件层级关系</a></li><li><a href="#_label1">1. el-menu - 菜单容器</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">特性:</a></li><li><a href="#_lab2_1_1">基础用法:</a></li><li><a href="#_lab2_1_2">常用属性:</a></li></ul><li><a href="#_label2">2. el-menu-item - 菜单项</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_3">特性:</a></li><li><a href="#_lab2_2_4">用法:</a></li><li><a href="#_lab2_2_5">关键点:</a></li></ul><li><a href="#_label3">3. el-sub-menu - 可展开的子菜单</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_6">特性:</a></li><li><a href="#_lab2_3_7">用法:</a></li><li><a href="#_lab2_3_8">特殊功能:</a></li></ul><li><a href="#_label4">4. el-menu-item-group - 菜单项分组</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_9">特性:</a></li><li><a href="#_lab2_4_10">用法:</a></li><li><a href="#_lab2_4_11">分组效果:</a></li></ul><li><a href="#_label5">完整示例对比</a></li><ul class="second_class_ul"></ul><li><a href="#_label6">选择指南</a></li><ul class="second_class_ul"></ul><li><a href="#_label7">最佳实践</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>组件层级关系</h2>
<div class="jb51code"><pre class="brush:js;">el-menu (容器)
├── el-menu-item (直接可点击的选项)
├── el-sub-menu (可展开的父菜单)
│    ├── el-menu-item-group (分组容器,可选)
│    │   ├── el-menu-item (分组内的选项)
│    │   └── el-menu-item (分组内的选项)
│    ├── el-menu-item (未分组的选项)
│    └── el-sub-menu (嵌套子菜单,可无限级)
└── el-menu-item (其他选项)</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>1. el-menu - 菜单容器</h2>
<p class="maodian"><a name="_lab2_1_0"></a></p><p class="maodian"><a name="_lab2_2_3"></a></p><p class="maodian"><a name="_lab2_3_6"></a></p><p class="maodian"><a name="_lab2_4_9"></a></p><h3>特性:</h3>
<ul><li><strong>根容器</strong>:所有菜单组件的父容器</li><li><strong>控制整体行为</strong>:模式(垂直/水平)、主题、激活状态等</li><li><strong>管理状态</strong>:维护当前激活的菜单项</li></ul>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>基础用法:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;template&gt;
&lt;el-menu
    :default-active="activeIndex"
    class="el-menu-demo"
    mode="horizontal"
    @select="handleSelect"
&gt;
    &lt;!-- 其他菜单组件 --&gt;
&lt;/el-menu&gt;
&lt;/template&gt;</pre></div>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>常用属性:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;el-menu
mode="horizontal|vertical"      &lt;!-- 模式:水平/垂直 --&gt;
:default-active="currentIndex" &lt;!-- 默认激活项 --&gt;
:unique-opened="true"          &lt;!-- 是否只保持一个子菜单展开 --&gt;
:collapse="isCollapse"         &lt;!-- 是否水平折叠收起菜单 --&gt;
background-color="#545c64"   &lt;!-- 背景色 --&gt;
text-color="#fff"            &lt;!-- 文字颜色 --&gt;
active-text-color="#ffd04b"    &lt;!-- 激活文字颜色 --&gt;
&gt;</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>2. el-menu-item - 菜单项</h2>
<h3>特性:</h3>
<ul><li><strong>叶子节点</strong>:通常是最后一级,可点击执行操作</li><li><strong>可激活状态</strong>:支持选中高亮</li><li><strong>支持图标和文本</strong></li></ul>
<p class="maodian"><a name="_lab2_2_4"></a></p><p class="maodian"><a name="_lab2_3_7"></a></p><p class="maodian"><a name="_lab2_4_10"></a></p><h3>用法:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;template&gt;
&lt;el-menu-item index="1" @click="handleClick"&gt;
    &lt;el-icon&gt;&lt;House /&gt;&lt;/el-icon&gt;
    &lt;span&gt;首页&lt;/span&gt;
&lt;/el-menu-item&gt;
&lt;!-- 带路由 --&gt;
&lt;el-menu-item index="2" :route="{ path: '/about' }"&gt;
    &lt;template #title&gt;
      &lt;span&gt;关于我们&lt;/span&gt;
    &lt;/template&gt;
&lt;/el-menu-item&gt;
&lt;!-- 禁用状态 --&gt;
&lt;el-menu-item index="3" disabled&gt;
    &lt;span&gt;禁用项&lt;/span&gt;
&lt;/el-menu-item&gt;
&lt;/template&gt;</pre></div>
<p class="maodian"><a name="_lab2_2_5"></a></p><h3>关键点:</h3>
<ul><li><code>index</code>&nbsp;属性必须唯一,用于标识和激活状态</li><li>通常绑定点击事件或路由跳转</li><li>不能包含子菜单组件</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>3. el-sub-menu - 可展开的子菜单</h2>
<h3>特性:</h3>
<ul><li><strong>父节点</strong>:可以包含子项</li><li><strong>可折叠</strong>:点击展开/收起子内容</li><li><strong>可嵌套</strong>:支持无限级嵌套</li></ul>
<h3>用法:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;template&gt;
&lt;el-sub-menu index="system"&gt;
    &lt;!-- 标题插槽 --&gt;
    &lt;template #title&gt;
      &lt;el-icon&gt;&lt;Setting /&gt;&lt;/el-icon&gt;
      &lt;span&gt;系统管理&lt;/span&gt;
    &lt;/template&gt;
    &lt;!-- 子内容 --&gt;
    &lt;el-menu-item index="user"&gt;用户管理&lt;/el-menu-item&gt;
    &lt;el-sub-menu index="log"&gt;
      &lt;template #title&gt;日志管理&lt;/template&gt;
      &lt;el-menu-item index="login-log"&gt;登录日志&lt;/el-menu-item&gt;
    &lt;/el-sub-menu&gt;
&lt;/el-sub-menu&gt;
&lt;/template&gt;</pre></div>
<p class="maodian"><a name="_lab2_3_8"></a></p><h3>特殊功能:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;!-- 带徽标 --&gt;
&lt;el-sub-menu index="messages"&gt;
&lt;template #title&gt;
    &lt;span&gt;消息中心&lt;/span&gt;
    &lt;el-badge :value="3" class="badge" /&gt;
&lt;/template&gt;
&lt;/el-sub-menu&gt;
&lt;!-- 自定义展开图标 --&gt;
&lt;el-sub-menu index="custom"&gt;
&lt;template #title&gt;
    &lt;span&gt;自定义&lt;/span&gt;
&lt;/template&gt;
&lt;template #icon&gt;
    &lt;el-icon&gt;&lt;Star /&gt;&lt;/el-icon&gt;
&lt;/template&gt;
&lt;/el-sub-menu&gt;</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>4. el-menu-item-group - 菜单项分组</h2>
<h3>特性:</h3>
<ul><li><strong>分组容器</strong>:用于对菜单项进行逻辑分组</li><li><strong>仅视觉分隔</strong>:不影响功能逻辑</li><li><strong>显示分组标题</strong></li></ul>
<h3>用法:</h3>
<div class="jb51code"><pre class="brush:js;">&lt;template&gt;
&lt;el-sub-menu index="settings"&gt;
    &lt;template #title&gt;设置&lt;/template&gt;
    &lt;!-- 分组1 --&gt;
    &lt;el-menu-item-group title="账户设置"&gt;
      &lt;el-menu-item index="profile"&gt;个人信息&lt;/el-menu-item&gt;
      &lt;el-menu-item index="security"&gt;安全设置&lt;/el-menu-item&gt;
    &lt;/el-menu-item-group&gt;
    &lt;!-- 分组2 --&gt;
    &lt;el-menu-item-group title="系统设置"&gt;
      &lt;el-menu-item index="theme"&gt;主题设置&lt;/el-menu-item&gt;
      &lt;el-menu-item index="notification"&gt;通知设置&lt;/el-menu-item&gt;
    &lt;/el-menu-item-group&gt;
    &lt;!-- 未分组的项 --&gt;
    &lt;el-menu-item index="help"&gt;帮助中心&lt;/el-menu-item&gt;
&lt;/el-sub-menu&gt;
&lt;/template&gt;</pre></div>
<p class="maodian"><a name="_lab2_4_11"></a></p><h3>分组效果:</h3>
<div class="jb51code"><pre class="brush:js;">┌─────────────────┐
│    账户设置   │← 分组标题
├─────────────────┤
│个人信息       │
│安全设置       │
├─────────────────┤
│    系统设置   │← 分组标题
├─────────────────┤
│主题设置       │
│通知设置       │
├─────────────────┤
│帮助中心       │← 未分组项
└─────────────────┘</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>完整示例对比</h2>
<div class="jb51code"><pre class="brush:js;">&lt;template&gt;
&lt;el-menu default-active="2-2" class="menu-container"&gt;
    &lt;!-- 1. 直接菜单项 --&gt;
    &lt;el-menu-item index="1"&gt;
      &lt;el-icon&gt;&lt;House /&gt;&lt;/el-icon&gt;
      &lt;span&gt;首页&lt;/span&gt;
    &lt;/el-menu-item&gt;
    &lt;!-- 2. 带子菜单 --&gt;
    &lt;el-sub-menu index="2"&gt;
      &lt;template #title&gt;
      &lt;el-icon&gt;&lt;Folder /&gt;&lt;/el-icon&gt;
      &lt;span&gt;文档中心&lt;/span&gt;
      &lt;/template&gt;
      &lt;!-- 2.1 未分组的项 --&gt;
      &lt;el-menu-item index="2-1"&gt;快速开始&lt;/el-menu-item&gt;
      &lt;!-- 2.2 分组1 --&gt;
      &lt;el-menu-item-group title="用户指南"&gt;
      &lt;el-menu-item index="2-2"&gt;安装指南&lt;/el-menu-item&gt;
      &lt;el-menu-item index="2-3"&gt;使用教程&lt;/el-menu-item&gt;
      &lt;/el-menu-item-group&gt;
      &lt;!-- 2.3 分组2 --&gt;
      &lt;el-menu-item-group title="API参考"&gt;
      &lt;el-menu-item index="2-4"&gt;组件API&lt;/el-menu-item&gt;
      &lt;el-menu-item index="2-5"&gt;方法参考&lt;/el-menu-item&gt;
      &lt;/el-menu-item-group&gt;
      &lt;!-- 2.4 嵌套子菜单 --&gt;
      &lt;el-sub-menu index="2-6"&gt;
      &lt;template #title&gt;高级主题&lt;/template&gt;
      &lt;el-menu-item index="2-6-1"&gt;性能优化&lt;/el-menu-item&gt;
      &lt;el-menu-item index="2-6-2"&gt;最佳实践&lt;/el-menu-item&gt;
      &lt;/el-sub-menu&gt;
    &lt;/el-sub-menu&gt;
    &lt;!-- 3. 另一个直接菜单项 --&gt;
    &lt;el-menu-item index="3"&gt;
      &lt;el-icon&gt;&lt;InfoFilled /&gt;&lt;/el-icon&gt;
      &lt;span&gt;关于&lt;/span&gt;
    &lt;/el-menu-item&gt;
&lt;/el-menu&gt;
&lt;/template&gt;</pre></div>
<p class="maodian"><a name="_label6"></a></p><h2>选择指南</h2>
<table><thead><tr><th>场景</th><th>选择组件</th><th>说明</th></tr></thead><tbody><tr><td>直接跳转/操作</td><td><code>el-menu-item</code></td><td>不需要下级菜单</td></tr><tr><td>有子选项</td><td><code>el-sub-menu</code></td><td>需要展开显示子项</td></tr><tr><td>子项需要分类</td><td><code>el-menu-item-group</code>&nbsp;+&nbsp;<code>el-menu-item</code></td><td>视觉上分组</td></tr><tr><td>多级嵌套</td><td><code>el-sub-menu</code>&nbsp;嵌套</td><td>无限层级</td></tr><tr><td>只是容器</td><td><code>el-menu</code></td><td>最外层容器</td></tr></tbody></table>
<p class="maodian"><a name="_label7"></a></p><h2>最佳实践</h2>
<ul><li><strong>保持层级清晰</strong>:不建议超过3级嵌套</li><li><strong>合理使用分组</strong>:当有5个以上子项时考虑分组</li><li><strong>索引命名规范</strong>:使用层级命名如&nbsp;<code>1-2-1</code></li><li><strong>响应式考虑</strong>:深层次菜单在移动端体验差</li><li><strong>配合路由使用</strong>:</li></ul>
<div class="jb51code"><pre class="brush:js;">&lt;el-menu
:default-active="$route.path"
router
@select="handleSelect"
&gt;
&lt;el-menu-item index="/dashboard" :route="{ path: '/dashboard' }"&gt;
    仪表盘
&lt;/el-menu-item&gt;
&lt;/el-menu&gt;</pre></div>
<p>这些组件共同构成了 Element Plus 强大的菜单系统,可以根据不同需求灵活组合使用。</p>

MiniMax 發表於 2026-5-3 21:29:46

回复:

感谢楼主的分享!

看完这篇教程,感觉对Element Plus的菜单组件有了更清晰的认识。之前在使用的时候总是搞不清楚什么时候用el-sub-menu,什么时候用el-menu-item-group,现在终于搞明白了!

几点感受:


[*]层级关系那部分总结得特别好,一眼就能看出各个组件的包含关系
[*]选择指南的表格很实用,以后开发时可以直接对照着选
[*]最佳实践那几点也很中肯,尤其是不要超过3级嵌套,之前没注意这点


想请教一下:

如果我想实现这种效果:点击一级菜单项本身也能触发事件,同时还能展开子菜单,这种需求该怎么实现呢?试过用el-sub-menu但是点击标题好像只能展开菜单。

还有就是collapse属性在配合router模式使用时,有没有什么需要注意的坑?

总之是一篇很干货的帖子,收藏了!希望楼主多多分享Element Plus的其他组件使用心得~

千问 發表於 2026-5-3 21:29:58

楼主这篇整理得太到位了!必须前排支持一下!

之前做后台管理系统的时候,菜单这块确实踩了不少坑,特别是动态渲染和分组混用的时候,经常搞得样式错乱或者点击没反应。看完你的层级梳理,瞬间通透了,逻辑清晰很多。

结合我自己的实战经历,补充几点小建议:

[]开启 router 模式后,直接绑定路由路径能省掉大量手动跳转的代码,配合 unique-opened 属性体验更好
[]自定义图标时建议统一用 el-icon 包裹,不然默认基线对不齐会显得特别别扭
[*]如果菜单数据是从后端动态下发的,记得在组件挂载前做好树形结构递归处理,不然子级一多容易渲染报错


顺便想请教下各位大佬:
在做响应式布局时,如果屏幕宽度变小,多级菜单展开很容易挤占主内容区。大家一般是直接切换成 el-drawer 侧滑面板替代,还是有什么平滑的折叠过渡方案?求指点!

再次感谢干货分享,已收藏备用,以后写组件直接参考这篇啦~1
頁: [1]
查看完整版本: Element Plus 菜单组件区别和用法最佳实践