Menu
Горизонтальная панель навигации для навигации верхнего уровня. Поддерживает выпадающие подменю, бейджи, иконки, темы, обработку переполнения, индикатор активного пункта, управление с клавиатуры и многое другое.
Для вертикальной боковой навигации см. Sidebar.
Basic
<script setup>
import { ref } from 'vue'
import { VxMenu } from 'veloxui'
const active = ref('home')
const items = [
{ key: 'home', label: 'Home', icon: 'home' },
{ key: 'inbox', label: 'Inbox', icon: 'mail' },
{ key: 'starred', label: 'Starred', icon: 'star' },
{ key: 'settings', label: 'Settings', icon: 'settings' },
]
</script>
<template>
<VxMenu v-model="active" :items="items" />
</template>Borderless
Установите :bordered="false", чтобы убрать границу и скругление углов.
<VxMenu v-model="active" :items="items" :bordered="false" />Custom Sizing
Настройте скругление меню, скругление пунктов и высоту пунктов.
<VxMenu v-model="active" :items="items" :radius="20" :item-radius="16" :item-height="44" />
<!-- Fully rounded pill style -->
<VxMenu v-model="active" :items="items" :radius="999" :item-radius="999" />With Badges
<VxMenu v-model="active" :items="[
{ key: 'inbox', label: 'Inbox', icon: 'mail', badge: 12, badgeType: 'primary' },
{ key: 'starred', label: 'Starred', icon: 'star', badge: 'New', badgeType: 'success' },
{ key: 'alerts', label: 'Alerts', icon: 'heart', badge: 3, badgeType: 'danger' },
{ key: 'settings', label: 'Settings', icon: 'settings' },
]" />Dropdown Submenus
Наведите курсор на родительский пункт, чтобы открыть его дочерние элементы. Родитель подсвечивается, когда активен дочерний элемент.
<VxMenu v-model="active" :items="[
{ key: 'home', label: 'Home', icon: 'home' },
{
key: 'projects',
label: 'Projects',
icon: 'folder',
children: [
{ key: 'design', label: 'Design System' },
{ key: 'api', label: 'API Platform' },
],
},
]" />Notification Dots
Небольшие цветные индикаторы на пунктах. По умолчанию красные, настраиваются через dotColor.
<VxMenu v-model="active" :items="[
{ key: 'inbox', label: 'Inbox', icon: 'mail', dot: true },
{ key: 'alerts', label: 'Alerts', icon: 'heart', dot: true, dotColor: '#f59e0b' },
]" />Active Indicator Bar
Установите indicator, чтобы показать анимированную нижнюю полоску, которая скользит к активному пункту.
<VxMenu v-model="active" :items="items" indicator />Sticky
Установите sticky, чтобы закрепить меню вверху контейнера прокрутки.
<VxMenu v-model="active" :items="items" sticky />Overflow
Когда пункты не помещаются, лишние сворачиваются в выпадающее меню «More».
<VxMenu v-model="active" :items="items" overflow />Loading
Показывает скелетон-заглушки, пока данные загружаются.
<VxMenu loading :loading-count="5" />Slots
Используйте слоты prefix и suffix, чтобы добавить содержимое вокруг пунктов. Используйте слот item, чтобы настроить отрисовку пункта.
<VxMenu v-model="active" :items="items">
<template #prefix>
<img src="/logo.svg" style="height: 24px; margin-right: 12px;" />
</template>
<template #suffix>
<VxButton size="sm" variant="outline">Sign In</VxButton>
</template>
<template #item="{ item, active }">
<button :class="{ 'my-custom-item': true, active }">
{{ item.label }}
</button>
</template>
</VxMenu>Router Integration
Используйте свойство to у пунктов для SPA-навигации через vue-router.
<VxMenu v-model="active" :items="[
{ key: 'home', label: 'Home', icon: 'home', to: '/' },
{ key: 'about', label: 'About', icon: 'user', to: '/about' },
{ key: 'docs', label: 'Docs', icon: 'file', to: { name: 'docs' } },
]" />Context Menu
Щёлкните правой кнопкой мыши на «Home» или «Inbox», чтобы увидеть контекстное меню. Поддерживает иконки, деструктивные (красные) пункты и отключённые пункты.
<VxMenu v-model="active" :items="[
{
key: 'inbox',
label: 'Inbox',
icon: 'mail',
contextMenu: [
{ label: 'Mark all read', icon: 'check', action: (item) => {} },
{ label: 'Settings', icon: 'settings', action: (item) => {} },
{ label: 'Delete all', icon: 'trash', destructive: true, action: (item) => {} },
],
},
]" />Responsive Drawer
Установите responsive, чтобы меню автоматически переключалось на кнопку-гамбургер на маленьких экранах. Потяните за ручку для изменения размера и посмотрите, как меню переключается между десктопным и мобильным режимами.
<VxMenu v-model="active" :items="items" responsive />
<!-- Custom breakpoint (default 768) -->
<VxMenu v-model="active" :items="items" responsive :breakpoint="640" />Потяните за нижний правый угол демо, чтобы изменить размер. Когда ширина опускается ниже брейкпоинта, меню сворачивается в иконку-гамбургер. Нажмите на неё, чтобы открыть плавный выдвижной drawer слева.
Custom Drawer Title
Используйте prop drawer-title, чтобы изменить текст заголовка, или слот drawer-header для полного контроля.
<!-- Simple title change -->
<VxMenu v-model="active" :items="items" responsive drawer-title="Navigation" />
<!-- Full custom header via slot -->
<VxMenu v-model="active" :items="items" responsive>
<template #drawer-header>
<img src="/logo.svg" style="height: 24px;" />
<span style="font-weight: 600;">My App</span>
</template>
</VxMenu>Custom Drawer Width
Используйте drawer-width, чтобы изменить ширину панели drawer. Принимает число (px) или строку.
<VxMenu v-model="active" :items="items" responsive :drawer-width="220" />
<VxMenu v-model="active" :items="items" responsive :drawer-width="360" />
<VxMenu v-model="active" :items="items" responsive drawer-width="50%" />Custom Burger & Close Icons
Используйте слот burger-icon для замены иконки-гамбургера и drawer-close-icon для замены иконки кнопки закрытия.
<VxMenu v-model="active" :items="items" responsive>
<!-- Three-dot burger icon -->
<template #burger-icon>
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/>
</svg>
</template>
<!-- Arrow-left close icon -->
<template #drawer-close-icon>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>
</svg>
</template>
</VxMenu>Dark Theme
<VxMenu v-model="active" :items="items" theme="dark" />Keyboard Navigation
Меню поддерживает полное управление с клавиатуры:
- Стрелка влево/вправо — перемещение фокуса между пунктами
- Стрелка вниз — открыть подменю
- Enter / Space — выбрать пункт в фокусе
- Escape — закрыть подменю или контекстное меню
- Home / End — перейти к первому/последнему пункту
API
VxMenu Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | MenuItem[] | [] | Пункты меню |
v-model | string | '' | Ключ активного пункта |
theme | 'light' | 'dark' | 'light' | Цветовая тема |
bordered | boolean | true | Показывать границу и скругление |
radius | number | string | 12 | Скругление меню (px) |
item-radius | number | string | 8 | Скругление пункта (px) |
item-height | number | string | 38 | Минимальная высота пункта (px) |
overflow | boolean | false | Сворачивать лишние пункты в выпадающее меню «More» |
indicator | boolean | false | Показывать анимированный индикатор активного пункта |
sticky | boolean | false | Закрепить меню вверху |
loading | boolean | false | Показывать скелетон-заглушки |
loading-count | number | 4 | Количество скелетон-пунктов |
responsive | boolean | false | Автоматический burger-меню на маленьких экранах |
breakpoint | number | 768 | Порог ширины для режима burger |
drawer-width | number | string | 280 | Ширина панели drawer |
drawer-title | string | 'Menu' | Текст заголовка drawer |
root-class | string | string[] | object | — | Класс на корне |
MenuItem
| Property | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Уникальный идентификатор |
label | string | Yes | Отображаемый текст |
icon | string | Component | No | Имя встроенной иконки или Vue-компонент |
disabled | boolean | No | Отключить этот пункт |
badge | string | number | No | Содержимое бейджа |
badgeType | 'default' | 'primary' | 'success' | 'warning' | 'danger' | No | Цвет бейджа |
divider | boolean | No | Показать разделитель перед |
action | (item) => void | No | Callback на клик |
children | MenuItem[] | No | Пункты выпадающего подменю |
to | string | object | No | Цель навигации Vue Router |
dot | boolean | No | Показать точку уведомления |
dotColor | string | No | Цвет точки (по умолчанию красный) |
contextMenu | ContextMenuItem[] | No | Пункты контекстного меню |
Slots
| Slot | Props | Description |
|---|---|---|
prefix | — | Содержимое перед пунктами меню |
suffix | — | Содержимое после пунктов меню |
item | { item, active } | Кастомная отрисовка пункта |
burger-icon | — | Кастомная иконка кнопки burger |
drawer-header | — | Кастомное содержимое заголовка drawer |
drawer-close-icon | — | Кастомная иконка кнопки закрытия drawer |
drawer-footer | — | Содержимое под пунктами drawer |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | (key: string) | Активный пункт изменён |
select | (key, item) | Пункт выбран |
context-menu | (item, event) | Клик правой кнопкой по пункту |