Компонент Menu в библиотеке Element Plus предназначен для построения навигационных меню с поддержкой вложенных пунктов, вертикальной или горизонтальной ориентации и гибкой кастомизации внешнего вида. Он тесно интегрирован с системой маршрутизации Vue и позволяет создавать как простые списки ссылок, так и сложные многоуровневые меню с подменю.
Основная структура Menu строится с использованием
элементов: el-menu, el-menu-item и
el-sub-menu.
Пример базовой структуры:
<template>
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal">
<el-menu-item index="1">Главная</el-menu-item>
<el-sub-menu index="2">
<template #title>Продукты</template>
<el-menu-item index="2-1">Продукт A</el-menu-item>
<el-menu-item index="2-2">Продукт B</el-menu-item>
</el-sub-menu>
<el-menu-item index="3">Контакты</el-menu-item>
</el-menu>
</template>
<script setup>
import { ref } from 'vue'
const activeIndex = ref('1')
</script>
Ключевые моменты:
el-menu поддерживает два режима: vertical
(по умолчанию) и horizontal.default-active задаёт активный пункт меню при первой
загрузке.el-sub-menu используется для создания вложенных
пунктов. Заголовок подменю определяется через слот
#title.el-menu поддерживает множество полезных свойств:
mode — ориентация меню (vertical,
horizontal, inline).default-active — индекс активного пункта.unique-opened — если установлено в true,
разрешает открывать только одно подменю одновременно.collapse — сворачивает меню в компактный вид, часто
используется вместе с боковыми панелями.background-color — цвет фона меню.text-color и active-text-color — цвет
текста пунктов и активного элемента соответственно.el-menu-item имеет ключевое свойство:
index — уникальный идентификатор пункта меню,
используемый для управления активностью и событиями.el-sub-menu расширяет функциональность:
index — уникальный идентификатор подменю.disabled — блокирует доступ к подменю.#title для кастомного заголовка.Menu предоставляет несколько событий для интерактивного управления:
select — срабатывает при выборе пункта меню, передаёт
index выбранного элемента.open — вызывается при открытии подменю.close — вызывается при закрытии подменю.Пример обработки событий:
<el-menu
:default-active="activeIndex"
@select="handleSelect"
@open="handleOpen"
@close="handleClose"
>
<el-menu-item index="1">Главная</el-menu-item>
<el-sub-menu index="2">
<template #title>Продукты</template>
<el-menu-item index="2-1">Продукт A</el-menu-item>
<el-menu-item index="2-2">Продукт B</el-menu-item>
</el-sub-menu>
</el-menu>
<script setup>
import { ref } from 'vue'
const activeIndex = ref('1')
function handleSelect(index) {
console.log('Выбран пункт:', index)
}
function handleOpen(index) {
console.log('Открыто подменю:', index)
}
function handleClose(index) {
console.log('Закрыто подменю:', index)
}
</script>
Для создания боковых панелей с компактным меню используется свойство
collapse:
<el-menu
:collapse="isCollapsed"
:default-active="activeIndex"
class="el-menu-vertical-demo"
>
<el-menu-item index="1">Главная</el-menu-item>
<el-sub-menu index="2">
<template #title>Продукты</template>
<el-menu-item index="2-1">Продукт A</el-menu-item>
</el-sub-menu>
</el-menu>
<script setup>
import { ref } from 'vue'
const activeIndex = ref('1')
const isCollapsed = ref(false)
</script>
collapse=true меню сворачивается, показывая только
иконки, если они заданы через слот #title или атрибут
icon.Горизонтальное меню идеально подходит для шапки сайта:
<el-menu mode="horizontal" :default-active="activeIndex">
<el-menu-item index="1" @click="goHome">Главная</el-menu-item>
<el-menu-item index="2" @click="goProducts">Продукты</el-menu-item>
</el-menu>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const activeIndex = ref('1')
function goHome() {
router.push({ name: 'Home' })
}
function goProducts() {
router.push({ name: 'Products' })
}
</script>
index удобно использовать для синхронизации с
default-active, чтобы выделять текущую страницу.Menu в Element Plus легко кастомизируется через CSS-переменные и классы:
.el-menu — контейнер меню..el-menu-item — отдельный пункт меню..el-sub-menu__title — заголовок подменю.Пример настройки цветов:
<el-menu
background-color="#001529"
text-color="#fff"
active-text-color="#409EFF"
:default-active="activeIndex"
>
<el-menu-item index="1">Главная</el-menu-item>
<el-menu-item index="2">Продукты</el-menu-item>
</el-menu>
background-color — фон всего меню.text-color — цвет текста пунктов.active-text-color — выделение активного пункта.Меню можно строить на основе массива данных, что упрощает работу с большим количеством пунктов:
<template>
<el-menu :default-active="activeIndex">
<template v-for="item in menuData">
<el-menu-item v-if="!item.children" :key="item.index" :index="item.index">
{{ item.label }}
</el-menu-item>
<el-sub-menu v-else :key="item.index" :index="item.index">
<template #title>{{ item.label }}</template>
<el-menu-item v-for="child in item.children" :key="child.index" :index="child.index">
{{ child.label }}
</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</template>
<script setup>
import { ref } from 'vue'
const activeIndex = ref('1')
const menuData = [
{ index: '1', label: 'Главная' },
{ index: '2', label: 'Продукты', children: [
{ index: '2-1', label: 'Продукт A' },
{ index: '2-2', label: 'Продукт B' },
]},
{ index: '3', label: 'Контакты' }
]
</script>
Для улучшения визуального восприятия часто используют иконки. В
Element Plus для этого применяется слот #title или атрибут
icon:
<el-menu :default-active="activeIndex">
<el-menu-item index="1">
<template #title>
<el-icon><HomeFilled /></el-icon>
Главная
</template>
</el-menu-item>
<el-sub-menu index="2">
<template #title>
<el-icon><Menu /></el-icon>
Продукты
</template>
<el-menu-item index="2-1">Продукт A</el-menu-item>
</el-sub-menu>
</el-menu>
<script setup>
import { ref } from 'vue'
import { HomeFilled, Menu } from '@element-plus/icons-vue'
const activeIndex = ref('1')
</script>
#title позволяет полностью кастомизировать
заголовок пункта меню.Эти возможности делают Menu в Element Plus гибким инструментом для создания навигации любого уровня сложности, от простых горизонтальных шапок до многоуровневых боковых панелей с динамическим содержимым.