6.2 el-menu
一、 <el-menu>
: 菜单组件,定义了侧边栏内部的具体导航项、层级结构和交互行为。
<el-container><!-- 侧边栏容器 --><el-aside width="200px"><!-- 菜单内容 --><el-menu default-active="1" class="el-menu-vertical-demo"><el-menu-item index="1"><i class="el-icon-menu"></i><span slot="title">导航一</span></el-menu-item><el-submenu index="2"><template slot="title"><i class="el-icon-location"></i><span>导航二</span></template><el-menu-item index="2-1">选项1</el-menu-item><el-menu-item index="2-2">选项2</el-menu-item></el-submenu></el-menu></el-aside><el-main>主内容区</el-main>
</el-container>
二、 <el-aside>
详解
<el-aside>
是布局系统的一部分,用于定义侧边栏区域。
- 作用: 提供一个固定宽度(或百分比)的垂直区域,通常放置导航菜单。
- 关键属性:
width
: 核心属性,设置侧边栏的宽度。可以是固定值 (200px
) 或百分比 (20%
)。这是控制侧边栏大小的主要方式。
- 与
<el-menu>
的关系:<el-aside>
只负责“这块区域有多大”,具体的菜单样式和行为由<el-menu>
控制。你可以给<el-menu>
添加height: 100%
来让它填满<el-aside>
的高度。
三、 <el-menu>
详解 (侧边栏的核心)
<el-menu>
是构建侧边栏功能的绝对核心。它非常强大,支持多种模式和丰富的配置。
1. 基本结构
<el-menu>
: 根菜单容器。<el-menu-item>
: 单个菜单项,代表一个可点击的导航链接。<el-submenu>
: 子菜单容器,用于创建可展开/折叠的二级(或更多级)菜单。
2. 关键属性
属性 | 类型 | 说明 | 重要性 |
---|---|---|---|
mode | string | 菜单展示模式。horizontal (水平) / vertical (垂直) / popmenu (弹出菜单,常用于移动端)。侧边栏必须设置为 vertical 。 | ⭐⭐⭐⭐⭐ |
default-active | string | 当前激活菜单的 index 。用于高亮显示当前页面对应的菜单项。通常与 Vue Router 的 $route.path 或 route.meta.activeMenu 结合使用。 | ⭐⭐⭐⭐⭐ |
unique-opened | boolean | 在 mode="vertical" 时是否只保持一个子菜单展开。true 表示手风琴效果,一次只展开一个。 | ⭐⭐⭐⭐ |
menu-trigger | string | 子菜单打开的触发方式,仅在 mode="horizontal" 时有效。hover / click 。 | ⭐ |
collapse | boolean | 是否水平折叠收起菜单(仅在 mode="vertical" 时可用)。true 时菜单收起为图标。这是实现“收起/展开”侧边栏功能的关键。 | ⭐⭐⭐⭐⭐ |
collapse-transition | boolean | 是否开启折叠动画。 | ⭐⭐ |
background-color | string | 菜单的背景色。 | ⭐⭐ |
text-color | string | 菜单的文字颜色。 | ⭐⭐ |
active-text-color | string | 当前激活菜单的文字颜色。 | ⭐⭐⭐ |
3. <el-menu-item>
和 <el-submenu>
属性
属性 | 类型 | 说明 |
---|---|---|
index | string | 唯一标识符。对于 <el-menu-item> ,点击后会触发 select 事件并传递此 index 。对于 <el-submenu> ,是其唯一标识,用于控制展开/收起和 unique-opened 逻辑。必须全局唯一。 |
route | object | string | Vue Router 的 route 对象或字符串。如果提供了此属性,当点击 <el-menu-item> 时,会触发 router.push 进行导航。这是实现菜单与路由联动的便捷方式。 |
disabled | boolean | 是否禁用。 |
4. 插槽 (Slots)
<el-menu-item>
的title
插槽: 用于自定义菜单项的标题内容(通常包含图标和文字)。<el-menu-item index="1"><i class="el-icon-document"></i><span slot="title">处理中心</span> </el-menu-item>
<el-submenu>
的title
插槽 (通过template
): 用于自定义子菜单的标题内容。<el-submenu index="2"><template slot="title"><i class="el-icon-location"></i><span>导航二</span></template><!-- 子菜单项 --> </el-submenu>
5. 事件 (Events)
select
: 当菜单项被选中时触发。回调参数为(index, indexPath)
,其中indexPath
是从根节点到当前节点的index
路径数组。这是实现菜单点击逻辑(如路由跳转、状态更新)的主要事件。open
: 当子菜单打开时触发。回调参数为(index, indexPath)
。close
: 当子菜单关闭时触发。回调参数为(index, indexPath)
。
四、 实现高级功能
1. 与 Vue Router 深度集成
这是最常见的需求。目标是:点击菜单项跳转路由,且当前页面对应的菜单项自动高亮。
<template><el-menu:default-active="$route.path" <!-- 关键1:绑定当前路由 -->mode="vertical"@select="handleSelect" <!-- 监听 select 事件 -->><el-menu-item index="/home"><i class="el-icon-menu"></i><span slot="title">首页</span></el-menu-item><el-menu-item index="/user"><i class="el-icon-user"></i><span slot="title">用户管理</span></el-menu-item><!-- 或者使用 route 属性 (更简洁) --><!-- <el-menu-item index="/order" :route="{ path: '/order' }"> --><!-- <i class="el-icon-tickets"></i> --><!-- <span slot="title">订单管理</span> --><!-- </el-menu-item> --></el-menu>
</template><script>
export default {watch: {// 关键2:监听路由变化,更新 default-active// 因为 default-active 是 prop,直接修改 $route.path 不会自动更新// 所以通常不需要额外 watch,只要 :default-active 绑定到 $route.path 就行了// 但如果菜单 index 和路由 path 不完全一致,就需要在这里处理映射'$route'(to) {// this.activeIndex = this.getMenuIndexByRoute(to); // 自定义映射逻辑}},methods: {handleSelect(index, indexPath) {// 关键3:处理点击// 如果没有使用 :route,需要手动跳转if (index !== this.$route.path) {this.$router.push(index);}}}
}
</script>
2. 实现“收起/展开”侧边栏
利用 <el-menu>
的 collapse
属性。
<template><div><!-- 收起/展开按钮 --><el-button @click="toggleCollapse">切换</el-button><el-aside :width="isCollapse ? '65px' : '200px'"> <!-- 动态改变 aside 宽度 --><el-menu:collapse="isCollapse" <!-- 绑定 collapse 状态 -->:collapse-transition="false" <!-- 可选:关闭动画更流畅 -->:default-active="$route.path"mode="vertical"><el-menu-item index="/home"><i class="el-icon-menu"></i><!-- 收起时只显示图标,展开时显示图标和文字 --><span slot="title" v-if="!isCollapse">首页</span></el-menu-item><!-- 其他菜单项... --></el-menu></el-aside></div>
</template><script>
export default {data() {return {isCollapse: false // 控制收起状态};},methods: {toggleCollapse() {this.isCollapse = !this.isCollapse;}}
}
</script>
3. 动态生成菜单 (基于数据)
从后端获取菜单数据,然后用 v-for
动态渲染。
<template><el-menu :default-active="activeIndex" mode="vertical"><template v-for="item in menuData"><el-menu-item v-if="!item.children" :key="item.index" :index="item.index":route="item.route"><i :class="item.icon"></i><span slot="title">{{ item.title }}</span></el-menu-item><el-submenu v-else :key="item.index" :index="item.index"><template slot="title"><i :class="item.icon"></i><span>{{ item.title }}</span></template><el-menu-item v-for="child in item.children" :key="child.index" :index="child.index":route="child.route">{{ child.title }}</el-menu-item></el-submenu></template></el-menu>
</template><script>
export default {data() {return {activeIndex: '/home',menuData: [{index: '1',title: '首页',icon: 'el-icon-menu',route: { path: '/home' }},{index: '2',title: '用户管理',icon: 'el-icon-user',children: [{ index: '2-1', title: '用户列表', route: { path: '/user/list' } },{ index: '2-2', title: '用户详情', route: { path: '/user/detail' } }]}]};}
}
</script>
4. 自定义主题
通过 background-color
, text-color
, active-text-color
属性或覆盖 CSS 变量来自定义侧边栏颜色。
<el-menubackground-color="#545c64"text-color="#fff"active-text-color="#ffd04b"...
><!-- 菜单项 -->
</el-menu>
或者通过 CSS 变量(如果 Element UI 版本支持):
/* 全局覆盖 */
.el-menu {--el-menu-bg-color: #545c64;--el-menu-text-color: #fff;--el-menu-active-color: #ffd04b;
}
五、 最佳实践与注意事项
index
唯一性: 确保所有<el-menu-item>
和<el-submenu>
的index
值在整个菜单树中是唯一的,否则default-active
和unique-opened
可能会出错。- 路由联动: 优先使用
<el-menu-item>
的route
属性来实现路由跳转,代码更简洁。如果逻辑复杂,再使用@select
事件。 - 高亮精准:
default-active
的值必须与$route.path
完全匹配才能高亮。注意路由的path
是否包含参数或是否是嵌套路由。必要时进行映射。 - 性能: 对于非常深或非常宽的菜单,考虑虚拟滚动或懒加载,但 Element UI 默认的
<el-menu>
对于一般后台系统性能足够。 - 无障碍: 确保菜单项有清晰的文本标签(
<span slot="title">
),方便屏幕阅读器识别。 - 响应式: 在移动端,考虑使用
<el-menu mode="popmenu">
或将侧边栏改为可滑动的抽屉 (<el-drawer>
)。
总结
Element UI 的侧边栏通过 <el-aside>
和 <el-menu>
的完美组合,提供了构建现代化后台导航的强大能力。掌握 <el-menu>
的各种属性、事件和与 Vue Router 的集成方式,是开发高效、用户体验良好的后台管理系统的关键。通过动态数据和收起/展开功能,可以构建出既美观又实用的侧边栏导航。