Sidebar
Вертикальная боковая панель навигации со сворачиваемыми подменю, поиском, перетаскиванием, изменением размера, группами, значками, свёрнутым режимом, мини-режимом и многим другим.
Для горизонтальной навигации см. Menu.
Basic
<script setup>
import { ref } from 'vue'
import { VxSidebar } from 'veloxui'
const active = ref('inbox')
const items = [
{ key: 'inbox', label: 'Inbox', icon: 'mail' },
{ key: 'starred', label: 'Starred', icon: 'star' },
{ key: 'drafts', label: 'Drafts', icon: 'file' },
{ key: 'trash', label: 'Trash', icon: 'trash' },
]
</script>
<template>
<VxSidebar v-model="active" :items="items" />
</template>With Badges
<VxSidebar 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' },
]" />Nested Submenus
Щёлкните по родительскому элементу, чтобы развернуть/свернуть его дочерние элементы.
<VxSidebar v-model="active" :items="[
{
key: 'projects',
label: 'Projects',
icon: 'folder',
children: [
{ key: 'design', label: 'Design System' },
{ key: 'api', label: 'API Platform' },
],
},
]" />Grouped
Группируйте элементы под заголовками разделов с помощью свойства group.
<VxSidebar v-model="active" :items="[
{ key: 'inbox', label: 'Inbox', icon: 'mail', group: 'Communication' },
{ key: 'chat', label: 'Chat', icon: 'heart', group: 'Communication' },
{ key: 'analytics', label: 'Analytics', icon: 'search', group: 'Workspace' },
]" />Notification Dots
Маленькие цветные индикаторы на элементах. По умолчанию красные, настраиваются через dotColor.
<VxSidebar v-model="active" :items="[
{ key: 'inbox', label: 'Inbox', icon: 'mail', dot: true },
{ key: 'chat', label: 'Chat', icon: 'heart', dot: true, dotColor: '#22c55e' },
]" />Searchable
Включите searchable, чтобы добавить поле поиска, фильтрующее элементы по подписи.
<VxSidebar v-model="active" :items="items" searchable />
<VxSidebar v-model="active" :items="items" searchable search-placeholder="Find..." />Collapsed
Переключите collapsed, чтобы показать только иконки с подсказками. Подменю появляются в виде выпадающих окон.
<script setup>
import { ref } from 'vue'
const active = ref('inbox')
const collapsed = ref(false)
const items = [
{ key: 'home', label: 'Home', icon: 'home' },
{ key: 'inbox', label: 'Inbox', icon: 'mail', badge: 5, badgeType: 'primary' },
{
key: 'projects',
label: 'Projects',
icon: 'folder',
children: [
{ key: 'design', label: 'Design System' },
{ key: 'api', label: 'API Platform' },
{ key: 'mobile', label: 'Mobile App' },
],
},
{
key: 'settings',
label: 'Settings',
icon: 'settings',
children: [
{ key: 'profile', label: 'Profile', icon: 'user' },
{ key: 'security', label: 'Security', icon: 'link' },
{ key: 'billing', label: 'Billing' },
],
},
{ key: 'logout', label: 'Log Out', icon: 'logout', divider: true },
]
</script>
<template>
<VxButton @click="collapsed = !collapsed">
{{ collapsed ? 'Expand' : 'Collapse' }}
</VxButton>
<VxSidebar v-model="active" :items="items" :collapsed="collapsed" />
</template>Mini Mode
При свёрнутом режиме с mini вместо иконок отображается первая буква каждой подписи.
<VxSidebar v-model="active" :items="items" collapsed mini />Resizable
Включите resizable, чтобы разрешить изменение размера перетаскиванием края боковой панели. Потяните за правый край.
<script setup>
import { ref } from 'vue'
import { VxSidebar } from 'veloxui'
const active = ref('inbox')
const collapsed = ref(false)
const items = [
{ key: 'inbox', label: 'Inbox', icon: 'mail' },
{ key: 'starred', label: 'Starred', icon: 'star' },
{ key: 'drafts', label: 'Drafts', icon: 'file' },
{ key: 'trash', label: 'Trash', icon: 'trash' },
]
</script>
<template>
<VxSidebar
v-model="active"
v-model:collapsed="collapsed"
:items="items"
resizable
:min-width="160"
:max-width="360"
/>
</template>Draggable
Включите draggable, чтобы разрешить переупорядочивание элементов верхнего уровня перетаскиванием.
<script setup>
import { ref } from 'vue'
import { VxSidebar } from 'veloxui'
const active = ref('inbox')
const items = ref([
{ key: 'inbox', label: 'Inbox', icon: 'mail' },
{ key: 'starred', label: 'Starred', icon: 'star' },
{ key: 'drafts', label: 'Drafts', icon: 'file' },
{ key: 'trash', label: 'Trash', icon: 'trash' },
{ key: 'settings', label: 'Settings', icon: 'settings' },
])
function onReorder(newItems) {
items.value = newItems
}
</script>
<template>
<VxSidebar v-model="active" :items="items" draggable @reorder="onReorder" />
</template>Router Integration
Используйте свойство to на элементах для SPA-навигации.
<VxSidebar v-model="active" :items="[
{ key: 'home', label: 'Home', icon: 'home', to: '/' },
{ key: 'about', label: 'About', icon: 'user', to: '/about' },
]" />Context Menu
Щёлкните правой кнопкой мыши по «Inbox» или «Starred», чтобы увидеть контекстное меню.
<script setup>
import { ref } from 'vue'
import { VxSidebar } from 'veloxui'
const active = ref('inbox')
const items = [
{
key: 'inbox',
label: 'Inbox',
icon: 'mail',
badge: 5,
badgeType: 'primary',
contextMenu: [
{ label: 'Mark all read', icon: 'check', action: (item) => {} },
{ label: 'Settings', icon: 'settings', action: (item) => {} },
{ label: 'Delete all', icon: 'trash', destructive: true, action: (item) => {} },
],
},
{
key: 'starred',
label: 'Starred',
icon: 'star',
contextMenu: [
{ label: 'Clear starred', icon: 'x', action: (item) => {} },
],
},
{ key: 'drafts', label: 'Drafts', icon: 'file' },
{ key: 'settings', label: 'Settings', icon: 'settings' },
]
</script>
<template>
<VxSidebar v-model="active" :items="items" />
</template>Loading
Показывайте скелетные плейсхолдеры, пока загружаются данные.
<VxSidebar loading :loading-count="6" />Dark Theme
<VxSidebar v-model="active" :items="items" theme="dark" />Accordion
Установите accordion, чтобы одновременно могло быть открыто только одно подменю. Щёлкните «Projects», затем «Settings» — открытым останется только одно.
<script setup>
import { ref } from 'vue'
import { VxSidebar } from 'veloxui'
const active = ref('home')
const items = [
{ key: 'home', label: 'Home', icon: 'home' },
{
key: 'projects',
label: 'Projects',
icon: 'folder',
children: [
{ key: 'design', label: 'Design System' },
{ key: 'api', label: 'API Platform' },
],
},
{
key: 'settings',
label: 'Settings',
icon: 'settings',
children: [
{ key: 'profile', label: 'Profile', icon: 'user' },
{ key: 'security', label: 'Security', icon: 'link' },
],
},
{ key: 'logout', label: 'Log Out', icon: 'logout' },
]
</script>
<template>
<VxSidebar v-model="active" :items="items" accordion />
</template>API
VxSidebar Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | MenuItem[] | [] | Элементы боковой панели |
v-model | string | '' | Ключ активного элемента |
collapsed | boolean | false | Свернуть до одних иконок |
theme | 'light' | 'dark' | 'light' | Цветовая тема |
accordion | boolean | false | Одновременно открыто только одно подменю |
indent | number | 24 | Отступ дочерних элементов в px |
collapsed-width | number | 48 | Ширина в свёрнутом режиме |
width | number | string | 240 | Ширина боковой панели |
rounded | boolean | true | Скруглённые углы элементов |
searchable | boolean | false | Показывать поле поиска |
search-placeholder | string | 'Search...' | Плейсхолдер поля поиска |
draggable | boolean | false | Включить переупорядочивание перетаскиванием |
mini | boolean | false | Показывать первую букву в свёрнутом режиме |
resizable | boolean | false | Включить маркер изменения размера |
min-width | number | 160 | Минимальная ширина при изменении размера |
max-width | number | 400 | Максимальная ширина при изменении размера |
scroll-shadow | boolean | true | Показывать тени прокрутки |
loading | boolean | false | Показывать скелетные плейсхолдеры |
loading-count | number | 6 | Количество скелетных элементов |
root-class | string | string[] | object | — | Класс на корневом элементе |
MenuItem
| Property | Type | Required | Description |
|---|---|---|---|
key | string | Да | Уникальный идентификатор |
label | string | Да | Отображаемый текст |
icon | string | Component | Нет | Имя встроенной иконки или Vue-компонент |
disabled | boolean | Нет | Отключить этот элемент |
badge | string | number | Нет | Содержимое значка |
badgeType | 'default' | 'primary' | 'success' | 'warning' | 'danger' | Нет | Цвет значка |
group | string | Нет | Подпись заголовка группы |
divider | boolean | Нет | Показать разделитель сверху |
action | (item) => void | Нет | Обработчик клика |
children | MenuItem[] | Нет | Вложенные элементы подменю |
to | string | object | Нет | Цель навигации Vue Router |
dot | boolean | Нет | Показать точку-уведомление |
dotColor | string | Нет | Цвет точки (по умолчанию красный) |
pinned | boolean | Нет | Закрепить элемент наверху |
contextMenu | ContextMenuItem[] | Нет | Элементы контекстного меню |
Slots
| Slot | Props | Description |
|---|---|---|
header | — | Содержимое над навигацией |
footer | — | Содержимое под навигацией |
item | { item, active } | Пользовательский рендеринг элемента |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | (key: string) | Активный элемент изменён |
update:collapsed | (collapsed: boolean) | Автосворачивание при размере меньше min-width |
select | (key, item) | Элемент выбран |
open-change | (openKeys: string[]) | Подменю открыто/закрыто |
search | (query: string) | Содержимое поиска изменилось |
reorder | (items: MenuItem[]) | Элементы переупорядочены перетаскиванием |
resize | (width: number) | Размер боковой панели изменён |
context-menu | (item, event) | Правый клик по элементу |
pin | (item) | Элемент закреплён/откреплён |
Exposed
| Name | Type | Description |
|---|---|---|
openKeys() | () => string[] | Получить ключи открытых подменю |
toggleOpen(key) | (key: string) => void | Переключить подменю |