Меню навигации
Компонент навигации по странице. Поддерживает горизонтальную / вертикальную раскладку, вложенные подменю, свёрнутое состояние, аккордеон; работа с клавиатурой соответствует паттерну меню APG.
Вертикальная раскладка (встроенные подменю)
В вертикальном встроенном режиме поддерживается навигация с клавиатуры: после раскрытия подменю ↑/↓ перемещают фокус через границы «конечный пункт ↔ заголовок подменю ↔ пункт внутри панели» (Home/End — к первому и последнему), отключённые пункты и пункты внутри свёрнутых панелей пропускаются.
- Главная
- Настройки▾
- Основные настройки
- Настройки безопасности
- Отключённый пункт
<script setup>
import { ref } from 'vue'
const active = ref('home')
const active2 = ref('settings2-basic')
</script>
<template>
<!-- Вертикальная раскладка -->
<LhMenu v-model="active">
<LhMenuItem index="home">Главная</LhMenuItem>
<LhSubMenu index="settings" title="Настройки">
<LhMenuItem index="settings-basic">Основные настройки</LhMenuItem>
<LhMenuItem index="settings-security">Настройки безопасности</LhMenuItem>
</LhSubMenu>
<LhMenuItem index="docs" disabled>Отключённый пункт</LhMenuItem>
</LhMenu>
</template><script>
export default {
data() {
return {
active: 'home',
active2: 'settings2-basic',
}
},
}
</script>
<template>
<!-- Вертикальная раскладка -->
<LhMenu v-model="active">
<LhMenuItem index="home">Главная</LhMenuItem>
<LhSubMenu index="settings" title="Настройки">
<LhMenuItem index="settings-basic">Основные настройки</LhMenuItem>
<LhMenuItem index="settings-security">Настройки безопасности</LhMenuItem>
</LhSubMenu>
<LhMenuItem index="docs" disabled>Отключённый пункт</LhMenuItem>
</LhMenu>
</template>Управление раскрытием
default-openeds — изначально раскрытые подменю; openeds (вместе с v-model:openeds) — контролируемое множество раскрытых; unique-opened — одновременно раскрыто только одно подменю. LhSubMenu также поддерживает disabled для полного отключения.
- Настройки (раскрыто по умолчанию)▾
- Основные настройки
- Настройки безопасности
- Управление (отключено)▾
- Управление пользователями
- О проекте
<script setup>
import { ref } from 'vue'
const active2 = ref('settings2-basic')
</script>
<template>
<!-- Управление раскрытием -->
<LhMenu
v-model="active2"
:default-openeds="['settings2']"
unique-opened
style="max-width: 240px"
>
<LhSubMenu index="settings2" title="Настройки (раскрыто по умолчанию)">
<LhMenuItem index="settings2-basic">Основные настройки</LhMenuItem>
<LhMenuItem index="settings2-security">Настройки безопасности</LhMenuItem>
</LhSubMenu>
<LhSubMenu index="manage" title="Управление (отключено)" disabled>
<LhMenuItem index="manage-users">Управление пользователями</LhMenuItem>
</LhSubMenu>
<LhMenuItem index="about2">О проекте</LhMenuItem>
</LhMenu>
</template><script>
export default {
data() {
return { active2: 'settings2-basic' }
},
}
</script>
<template>
<!-- Управление раскрытием -->
<LhMenu
v-model="active2"
:default-openeds="['settings2']"
unique-opened
style="max-width: 240px"
>
<LhSubMenu index="settings2" title="Настройки (раскрыто по умолчанию)">
<LhMenuItem index="settings2-basic">Основные настройки</LhMenuItem>
<LhMenuItem index="settings2-security">Настройки безопасности</LhMenuItem>
</LhSubMenu>
<LhSubMenu index="manage" title="Управление (отключено)" disabled>
<LhMenuItem index="manage-users">Управление пользователями</LhMenuItem>
</LhSubMenu>
<LhMenuItem index="about2">О проекте</LhMenuItem>
</LhMenu>
</template>- Настройки▾
- Основные настройки
<script setup lang="ts">
import { ref } from 'vue'
const active2 = ref('settings2-basic')
</script>
<template>
<!-- Контролируемое множество раскрытых -->
<LhMenu v-model="active2" :openeds="['settings2']">
<LhSubMenu index="settings2" title="Настройки">
<LhMenuItem index="settings2-basic">Основные настройки</LhMenuItem>
</LhSubMenu>
</LhMenu>
</template><script>
export default {
data() {
return { active2: 'settings2-basic' }
},
}
</script>
<template>
<!-- Контролируемое множество раскрытых -->
<LhMenu v-model="active2" :openeds="['settings2']">
<LhSubMenu index="settings2" title="Настройки">
<LhMenuItem index="settings2-basic">Основные настройки</LhMenuItem>
</LhSubMenu>
</LhMenu>
</template>Горизонтальная раскладка (выпадающие подменю)
- Главная
- Настройки▾
<script setup lang="ts">
import { ref } from 'vue'
const active = ref('home')
</script>
<template>
<!-- Горизонтальная раскладка -->
<LhMenu v-model="active" mode="horizontal">
<LhMenuItem index="home">Главная</LhMenuItem>
<LhSubMenu index="settings" title="Настройки">
<LhMenuItem index="settings-basic">Основные настройки</LhMenuItem>
</LhSubMenu>
</LhMenu>
</template><script>
export default {
data() {
return { active: 'home' }
},
}
</script>
<template>
<!-- Горизонтальная раскладка -->
<LhMenu v-model="active" mode="horizontal">
<LhMenuItem index="home">Главная</LhMenuItem>
<LhSubMenu index="settings" title="Настройки">
<LhMenuItem index="settings-basic">Основные настройки</LhMenuItem>
</LhSubMenu>
</LhMenu>
</template>Свёрнутое состояние и группы
- Контент
- Главная
<script setup lang="ts">
import { ref } from 'vue'
const active = ref('home')
</script>
<template>
<!-- Сворачивание + группы -->
<LhMenu v-model="active" collapse>
<LhMenuItemGroup title="Контент">
<LhMenuItem index="home">Главная</LhMenuItem>
</LhMenuItemGroup>
</LhMenu>
</template><script>
export default {
data() {
return { active: 'home' }
},
}
</script>
<template>
<!-- Сворачивание + группы -->
<LhMenu v-model="active" collapse>
<LhMenuItemGroup title="Контент">
<LhMenuItem index="home">Главная</LhMenuItem>
</LhMenuItemGroup>
</LhMenu>
</template>API
LhMenu Props
| Свойство | Описание | Тип | По умолчанию |
|---|---|---|---|
| modelValue | Текущий активный пункт (контролируемый v-model; при отсутствии поддерживается внутри компонента) | string | — |
| mode | Режим раскладки | "horizontal" | "vertical" | 'vertical' |
| collapse | В вертикальном режиме сворачивается до панели иконок (подменю превращаются во всплывающие панели) | boolean | false |
| defaultOpeneds | Ключи раскрытых по умолчанию подменю (неконтролируемые) | string[] | () => [] |
| openeds | Ключи раскрытых подменю (контролируемые) | string[] | — |
| uniqueOpened | Аккордеон: одновременно раскрыто только одно подменю | boolean | false |
| sx | Свойства быстрой разметки sx | LhSxProps | — |
Events
| Событие | Описание | Параметры обратного вызова |
|---|---|---|
| update:modelValue | Срабатывает при изменении активного пункта (v-model) | (value: string) |
| update:openeds | Срабатывает при изменении множества раскрытых подменю (v-model:openeds) | (value: string[]) |
| select | Срабатывает при выборе пункта меню | (index: string, indexPath: string[]) |
| open | Срабатывает при раскрытии подменю | (index: string, indexPath: string[]) |
| close | Срабатывает при сворачивании подменю | (index: string, indexPath: string[]) |
LhMenuItem Props
| Свойство | Описание | Тип | По умолчанию |
|---|---|---|---|
| index | Уникальный идентификатор (обязательный) | string | — |
| disabled | Отключён | boolean | false |
| sx | Свойства быстрой разметки sx | LhSxProps | — |
Событие: click(index); слот: default.
LhSubMenu Props
| Свойство | Описание | Тип | По умолчанию |
|---|---|---|---|
| index | Уникальный идентификатор (обязательный) | string | — |
| title | Заголовок (можно также использовать слот title) | string | — |
| disabled | Отключён | boolean | false |
| sx | Свойства быстрой разметки sx | LhSxProps | — |
Событие: select(index, indexPath) (всплывает); слоты: title, default (допускает дальнейшую вложенность LhSubMenu).
LhMenuItemGroup Props
| Свойство | Описание | Тип | По умолчанию |
|---|---|---|---|
| title | Заголовок группы (можно также использовать слот title) | string | — |
| sx | Свойства быстрой разметки sx | LhSxProps | — |
Слоты: title, default.
Доступность
- Горизонтальному режиму соответствует
role="menubar", вертикальному —role="menu"; пунктам —role="menuitem", группам —role="group"(контейнерrole="presentation") - Заголовок подменю связывается с панелью через
aria-haspopup+aria-expanded+aria-controls - Клавиатура: Enter/Space/→ раскрывают подменю и переводят фокус на первый пункт, ← сворачивает, Esc закрывает; в вертикальном встроенном режиме ↑/↓/Home/End перемещаются по видимым пунктам (конечные пункты, заголовки подменю и пункты в раскрытых панелях) через границы с зацикливанием, отключённые пункты и пункты внутри свёрнутых панелей пропускаются
- Высота встроенного раскрытия задаётся через CSS
grid-template-rows: 0fr/1fr(измерение высоты на JS не требуется); всплывающие панели позиционируются движком popper (flip/shift, сворачивание при выходе за пределы viewport)
Определения типов
Структуры TypeScript, экспортируемые этим компонентом (автоматически извлечены из packages/components/menu/src/types.ts и исходников @lh-ui/share/core/*; нажмите на каждый пункт, чтобы развернуть полное определение; описания свойств см. в таблице Props выше):
LhMenuProps
/** Props меню */
export interface LhMenuProps {
/** Текущий активный пункт (контролируемый v-model; при отсутствии поддерживается внутри компонента) */
modelValue?: string
/** Режим раскладки */
mode?: LhMenuMode
/** В вертикальном режиме сворачивается до панели иконок (подменю превращаются во всплывающие панели) */
collapse?: boolean
/** Ключи раскрытых по умолчанию подменю (неконтролируемые) */
defaultOpeneds?: string[]
/** Ключи раскрытых подменю (контролируемые) */
openeds?: string[]
/** Аккордеон: одновременно раскрыто только одно подменю */
uniqueOpened?: boolean
/** Свойства быстрой разметки sx */
sx?: LhSxProps
}LhMenuItemProps
/** Props конечного пункта */
export interface LhMenuItemProps {
/** Уникальный идентификатор (обязательный) */
index: string
disabled?: boolean
/** Свойства быстрой разметки sx */
sx?: LhSxProps
}LhSubMenuProps
/** Props подменю (допускает рекурсивную вложенность) */
export interface LhSubMenuProps {
/** Уникальный идентификатор (обязательный) */
index: string
/** Заголовок (можно также использовать слот title) */
title?: string
disabled?: boolean
/** Свойства быстрой разметки sx */
sx?: LhSxProps
}LhMenuItemGroupProps
/** Props группы */
export interface LhMenuItemGroupProps {
/** Заголовок группы (можно также использовать слот title) */
title?: string
/** Свойства быстрой разметки sx */
sx?: LhSxProps
}LhMenuMode (из @lh-ui/share/core/menu)
/** Режим раскладки меню */
export type LhMenuMode = 'horizontal' | 'vertical'