|
@@ -0,0 +1,561 @@
|
|
|
|
|
+# Компонент MultiLevelMenu - Полная документация
|
|
|
|
|
+
|
|
|
|
|
+## Назначение компонента
|
|
|
|
|
+
|
|
|
|
|
+`MultiLevelMenu` - универсальный компонент для создания многоуровневых навигационных меню с поддержкой вложенности, различных тем, адаптивным дизайном и расширенной функциональностью. Компонент автоматически обрабатывает иерархическую структуру данных и предоставляет интуитивную навигацию.
|
|
|
|
|
+
|
|
|
|
|
+## git репозитарий
|
|
|
|
|
+https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master/vue/app/shared/ImageSlider/
|
|
|
|
|
+
|
|
|
|
|
+## Импорт и регистрация
|
|
|
|
|
+
|
|
|
|
|
+```coffee
|
|
|
|
|
+# В основном файле приложения (app/temp.coffee)
|
|
|
|
|
+components:
|
|
|
|
|
+ 'multilevelmenu': require 'app/shared/MultiLevelMenu'
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Базовое использование
|
|
|
|
|
+
|
|
|
|
|
+### Минимальная конфигурация
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### С кастомными настройками
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="navigationData"
|
|
|
|
|
+ theme="dark"
|
|
|
|
|
+ orientation="horizontal"
|
|
|
|
|
+ :showIcons="true"
|
|
|
|
|
+ :autoClose="true"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Полный список props
|
|
|
|
|
+
|
|
|
|
|
+### `menuItems` (обязательный)
|
|
|
|
|
+- **Тип:** `Array`
|
|
|
|
|
+- **Описание:** Массив объектов пунктов меню
|
|
|
|
|
+- **Структура объекта:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ {
|
|
|
|
|
+ id: String # Уникальный идентификатор
|
|
|
|
|
+ title: String | Array # Заголовок пункта (поддерживает мультиязычные массивы)
|
|
|
|
|
+ url: String # Ссылка или маршрут
|
|
|
|
|
+ icon: String # Иконка (название или путь)
|
|
|
|
|
+ children: Array # Вложенные пункты меню
|
|
|
|
|
+ type: String # Тип пункта ('link', 'button', 'divider')
|
|
|
|
|
+ disabled: Boolean # Отключенное состояние
|
|
|
|
|
+ visible: Boolean # Видимость пункта
|
|
|
|
|
+ target: String # Целевое окно для ссылок
|
|
|
|
|
+ permissions: Array # Права доступа
|
|
|
|
|
+ badge: String | Number # Бейдж/уведомление
|
|
|
|
|
+ badgeColor: String # Цвет бейджа
|
|
|
|
|
+ }
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `theme` (опциональный)
|
|
|
|
|
+- **Тип:** `String`
|
|
|
|
|
+- **По умолчанию:** `'light'`
|
|
|
|
|
+- **Допустимые значения:** `'light'`, `'dark'`, `'primary'`, `'custom'`
|
|
|
|
|
+- **Описание:** Цветовая тема меню
|
|
|
|
|
+
|
|
|
|
|
+### `orientation` (опциональный)
|
|
|
|
|
+- **Тип:** `String`
|
|
|
|
|
+- **По умолчанию:** `'horizontal'`
|
|
|
|
|
+- **Допустимые значения:** `'horizontal'`, `'vertical'`
|
|
|
|
|
+- **Описание:** Ориентация меню
|
|
|
|
|
+
|
|
|
|
|
+### `showIcons` (опциональный)
|
|
|
|
|
+- **Тип:** `Boolean`
|
|
|
|
|
+- **По умолчанию:** `true`
|
|
|
|
|
+- **Описание:** Показывать иконки пунктов меню
|
|
|
|
|
+
|
|
|
|
|
+### `autoClose` (опциональный)
|
|
|
|
|
+- **Тип:** `Boolean`
|
|
|
|
|
+- **По умолчанию:** `true`
|
|
|
|
|
+- **Описание:** Автоматически закрывать выпадающие меню при клике вне области
|
|
|
|
|
+
|
|
|
|
|
+### `maxDepth` (опциональный)
|
|
|
|
|
+- **Тип:** `Number`
|
|
|
|
|
+- **По умолчанию:** `3`
|
|
|
|
|
+- **Описание:** Максимальная глубина вложенности меню
|
|
|
|
|
+
|
|
|
|
|
+### `activeItem` (опциональный)
|
|
|
|
|
+- **Тип:** `String`
|
|
|
|
|
+- **По умолчанию:** `null`
|
|
|
|
|
+- **Описание:** ID активного пункта меню
|
|
|
|
|
+
|
|
|
|
|
+### `mobileBreakpoint` (опциональный)
|
|
|
|
|
+- **Тип:** `Number`
|
|
|
|
|
+- **По умолчанию:** `768`
|
|
|
|
|
+- **Описание:** Breakpoint для мобильной версии (в px)
|
|
|
|
|
+
|
|
|
|
|
+### `animationType` (опциональный)
|
|
|
|
|
+- **Тип:** `String`
|
|
|
|
|
+- **По умолчанию:** `'fade'`
|
|
|
|
|
+- **Допустимые значения:** `'fade'`, `'slide'`, `'scale'`, `'none'`
|
|
|
|
|
+- **Описание:** Тип анимации выпадающих меню
|
|
|
|
|
+
|
|
|
|
|
+## События (Events)
|
|
|
|
|
+
|
|
|
|
|
+### `@item-click`
|
|
|
|
|
+- **Описание:** Событие клика по пункту меню
|
|
|
|
|
+- **Payload:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ {
|
|
|
|
|
+ item: Object, # Объект пункта меню
|
|
|
|
|
+ event: Event, # Нативное событие
|
|
|
|
|
+ level: Number, # Уровень вложенности
|
|
|
|
|
+ path: Array # Путь от корня
|
|
|
|
|
+ }
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `@item-hover`
|
|
|
|
|
+- **Описание:** Событие наведения на пункт меню
|
|
|
|
|
+- **Payload:** Аналогично `item-click`
|
|
|
|
|
+
|
|
|
|
|
+### `@menu-open`
|
|
|
|
|
+- **Описание:** Событие открытия подменю
|
|
|
|
|
+- **Payload:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ {
|
|
|
|
|
+ item: Object, # Родительский пункт
|
|
|
|
|
+ level: Number, # Уровень
|
|
|
|
|
+ items: Array # Дочерние пункты
|
|
|
|
|
+ }
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `@menu-close`
|
|
|
|
|
+- **Описание:** Событие закрытия подменю
|
|
|
|
|
+- **Payload:** Аналогично `menu-open`
|
|
|
|
|
+
|
|
|
|
|
+### `@active-change`
|
|
|
|
|
+- **Описание:** Событие изменения активного пункта
|
|
|
|
|
+- **Payload:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ {
|
|
|
|
|
+ oldItem: Object, # Предыдущий активный пункт
|
|
|
|
|
+ newItem: Object, # Новый активный пункт
|
|
|
|
|
+ level: Number # Уровень изменения
|
|
|
|
|
+ }
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+## Слоты (Slots)
|
|
|
|
|
+
|
|
|
|
|
+### `[item-content]` (кастомизация содержимого пункта)
|
|
|
|
|
+- **Props:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ {
|
|
|
|
|
+ item: Object, # Объект пункта меню
|
|
|
|
|
+ level: Number, # Уровень вложенности
|
|
|
|
|
+ isActive: Boolean, # Активное состояние
|
|
|
|
|
+ hasChildren: Boolean # Наличие дочерних элементов
|
|
|
|
|
+ }
|
|
|
|
|
+ ```
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```pug
|
|
|
|
|
+ multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+ template([item-content]="{ item, level, isActive }")
|
|
|
|
|
+ div(class="flex items-center space-x-3")
|
|
|
|
|
+ icon(:name="item.icon" class="w-5 h-5")
|
|
|
|
|
+ span {{ item.title }}
|
|
|
|
|
+ badge(v-if="item.badge" :count="item.badge")
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `[item-icon]` (кастомизация иконки)
|
|
|
|
|
+- **Props:** Аналогично `item-content`
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```pug
|
|
|
|
|
+ multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+ template([item-icon]="{ item }")
|
|
|
|
|
+ custom-icon(:name="item.icon")
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `[item-badge]` (кастомизация бейджа)
|
|
|
|
|
+- **Props:** Аналогично `item-content`
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```pug
|
|
|
|
|
+ multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+ template([item-badge]="{ item }")
|
|
|
|
|
+ div(class="bg-red-500 text-white rounded-full px-2 py-1 text-xs")
|
|
|
|
|
+ {{ item.badge }}
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `[before-menu]` (контент перед меню)
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```pug
|
|
|
|
|
+ multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+ template([before-menu])
|
|
|
|
|
+ div(class="p-4 border-b")
|
|
|
|
|
+ p Добро пожаловать!
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `[after-menu]` (контент после меню)
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```pug
|
|
|
|
|
+ multilevelmenu(:menuItems="menuData")
|
|
|
|
|
+ template([after-menu])
|
|
|
|
|
+ div(class="p-4 border-t")
|
|
|
|
|
+ app-link(to="/help") Помощь
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+## Методы компонента
|
|
|
|
|
+
|
|
|
|
|
+### `openSubmenu(itemId)`
|
|
|
|
|
+- **Описание:** Программное открытие подменю
|
|
|
|
|
+- **Параметры:** `itemId` - ID пункта меню
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ @$refs.menu.openSubmenu('events')
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `closeSubmenu(itemId)`
|
|
|
|
|
+- **Описание:** Программное закрытие подменю
|
|
|
|
|
+- **Параметры:** `itemId` - ID пункта меню
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ @$refs.menu.closeSubmenu('events')
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `closeAll()`
|
|
|
|
|
+- **Описание:** Закрыть все открытые подменю
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ @$refs.menu.closeAll()
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `setActive(itemId)`
|
|
|
|
|
+- **Описание:** Установить активный пункт меню
|
|
|
|
|
+- **Параметры:** `itemId` - ID пункта меню
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ @$refs.menu.setActive('current-page')
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `updateMenu(newItems)`
|
|
|
|
|
+- **Описание:** Обновить данные меню
|
|
|
|
|
+- **Параметры:** `newItems` - новый массив пунктов меню
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ @$refs.menu.updateMenu(updatedMenuData)
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `getActiveItem()`
|
|
|
|
|
+- **Описание:** Получить текущий активный пункт
|
|
|
|
|
+- **Возвращает:** Объект активного пункта меню
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ activeItem = @$refs.menu.getActiveItem()
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+### `getMenuPath(itemId)`
|
|
|
|
|
+- **Описание:** Получить путь к пункту меню
|
|
|
|
|
+- **Параметры:** `itemId` - ID пункта меню
|
|
|
|
|
+- **Возвращает:** Массив ID от корня до пункта
|
|
|
|
|
+- **Пример:**
|
|
|
|
|
+ ```coffee
|
|
|
|
|
+ path = @$refs.menu.getMenuPath('deep-item')
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+## Примеры использования в различных сценариях
|
|
|
|
|
+
|
|
|
|
|
+### 1. Основная навигация сайта
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="mainNavigation"
|
|
|
|
|
+ theme="light"
|
|
|
|
|
+ orientation="horizontal"
|
|
|
|
|
+ :showIcons="false"
|
|
|
|
|
+ @item-click="handleNavClick"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 2. Боковое меню администратора
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="adminMenu"
|
|
|
|
|
+ theme="dark"
|
|
|
|
|
+ orientation="vertical"
|
|
|
|
|
+ :maxDepth="4"
|
|
|
|
|
+ :activeItem="currentAdminSection"
|
|
|
|
|
+ @active-change="onAdminSectionChange"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. Мобильное меню с кастомизацией
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="mobileMenu"
|
|
|
|
|
+ theme="primary"
|
|
|
|
|
+ orientation="vertical"
|
|
|
|
|
+ :mobileBreakpoint="1024"
|
|
|
|
|
+ :animationType="slide"
|
|
|
|
|
+)
|
|
|
|
|
+ template([item-content]="{ item, level }")
|
|
|
|
|
+ div(class="flex items-center justify-between py-3")
|
|
|
|
|
+ div(class="flex items-center space-x-4")
|
|
|
|
|
+ icon(:name="item.icon" class="w-6 h-6")
|
|
|
|
|
+ span(class="text-lg") {{ item.title }}
|
|
|
|
|
+ icon(
|
|
|
|
|
+ v-if="item.children"
|
|
|
|
|
+ name="chevron-right"
|
|
|
|
|
+ class="w-4 h-4 transform transition-transform"
|
|
|
|
|
+ :class="{ 'rotate-90': isOpen }"
|
|
|
|
|
+ )
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4. Меню с правами доступа
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="filteredMenu"
|
|
|
|
|
+ @item-click="checkPermissions"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5. Мега-меню с различными типами контента
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(:menuItems="megaMenuData")
|
|
|
|
|
+ template([item-content]="{ item, level }")
|
|
|
|
|
+ div(v-if="level === 1 && item.type === 'mega'")
|
|
|
|
|
+ div(class="grid grid-cols-3 gap-8 p-6")
|
|
|
|
|
+ div(v-for="section in item.sections")
|
|
|
|
|
+ h4(class="font-semibold mb-3") {{ section.title }}
|
|
|
|
|
+ div(class="space-y-2")
|
|
|
|
|
+ app-link(
|
|
|
|
|
+ v-for="link in section.links"
|
|
|
|
|
+ :to="link.url"
|
|
|
|
|
+ class="block text-gray-600 hover:text-blue-600"
|
|
|
|
|
+ ) {{ link.title }}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Структура данных меню
|
|
|
|
|
+
|
|
|
|
|
+### Базовый пример
|
|
|
|
|
+```coffee
|
|
|
|
|
+menuData = [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'home'
|
|
|
|
|
+ title: ['Главная', 'Home', 'Асосӣ']
|
|
|
|
|
+ url: '/'
|
|
|
|
|
+ icon: 'home'
|
|
|
|
|
+ visible: true
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'events'
|
|
|
|
|
+ title: ['Мероприятия', 'Events', 'Чорабиниҳо']
|
|
|
|
|
+ url: '/events'
|
|
|
|
|
+ icon: 'calendar'
|
|
|
|
|
+ children: [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'concerts'
|
|
|
|
|
+ title: ['Концерты', 'Concerts', 'Консертҳо']
|
|
|
|
|
+ url: '/events/concerts'
|
|
|
|
|
+ icon: 'music'
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'exhibitions'
|
|
|
|
|
+ title: ['Выставки', 'Exhibitions', 'Намоишҳо']
|
|
|
|
|
+ url: '/events/exhibitions'
|
|
|
|
|
+ icon: 'palette'
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'blog'
|
|
|
|
|
+ title: ['Блог', 'Blog', 'Блог']
|
|
|
|
|
+ url: '/blog'
|
|
|
|
|
+ icon: 'news'
|
|
|
|
|
+ badge: 5
|
|
|
|
|
+ badgeColor: 'red'
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ type: 'divider'
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'contacts'
|
|
|
|
|
+ title: ['Контакты', 'Contacts', 'Тамос']
|
|
|
|
|
+ url: '/contacts'
|
|
|
|
|
+ icon: 'phone'
|
|
|
|
|
+ disabled: false
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Расширенная структура с пермишенами
|
|
|
|
|
+```coffee
|
|
|
|
|
+advancedMenu = [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'dashboard'
|
|
|
|
|
+ title: 'Дашборд'
|
|
|
|
|
+ url: '/admin'
|
|
|
|
|
+ icon: 'dashboard'
|
|
|
|
|
+ permissions: ['admin', 'moderator']
|
|
|
|
|
+ children: [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'users'
|
|
|
|
|
+ title: 'Пользователи'
|
|
|
|
|
+ url: '/admin/users'
|
|
|
|
|
+ permissions: ['admin']
|
|
|
|
|
+ }
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 'content'
|
|
|
|
|
+ title: 'Контент'
|
|
|
|
|
+ url: '/admin/content'
|
|
|
|
|
+ permissions: ['admin', 'editor']
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Темы и стилизация
|
|
|
|
|
+
|
|
|
|
|
+### Встроенные темы
|
|
|
|
|
+- **light** - светлая тема с белым фоном
|
|
|
|
|
+- **dark** - темная тема с серым фоном
|
|
|
|
|
+- **primary** - тема с основным цветом бренда
|
|
|
|
|
+- **custom** - для полной кастомизации через CSS
|
|
|
|
|
+
|
|
|
|
|
+### Кастомизация через CSS переменные
|
|
|
|
|
+```styl
|
|
|
|
|
+.multilevel-menu
|
|
|
|
|
+ --menu-bg: theme('colors.white')
|
|
|
|
|
+ --menu-text: theme('colors.gray.800')
|
|
|
|
|
+ --menu-hover-bg: theme('colors.gray.100')
|
|
|
|
|
+ --menu-active-bg: theme('colors.blue.500')
|
|
|
|
|
+ --menu-active-text: theme('colors.white')
|
|
|
|
|
+ --menu-border: theme('colors.gray.200')
|
|
|
|
|
+ --menu-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Кастомизация через классы
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="menuData"
|
|
|
|
|
+ class="custom-menu"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```styl
|
|
|
|
|
+.custom-menu
|
|
|
|
|
+ .menu-item
|
|
|
|
|
+ @apply px-6 py-3 border-l-4 border-transparent
|
|
|
|
|
+
|
|
|
|
|
+ &.active
|
|
|
|
|
+ @apply border-blue-500 bg-blue-50
|
|
|
|
|
+
|
|
|
|
|
+ &:hover
|
|
|
|
|
+ @apply bg-gray-50
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Адаптивность и мобильная версия
|
|
|
|
|
+
|
|
|
|
|
+### Автоматическая адаптация
|
|
|
|
|
+- Горизонтальное меню на десктопе
|
|
|
|
|
+- Вертикальное выдвижное меню на мобильных
|
|
|
|
|
+- Настраиваемый breakpoint
|
|
|
|
|
+- Touch-оптимизированные взаимодействия
|
|
|
|
|
+
|
|
|
|
|
+### Кастомизация мобильной версии
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="menuData"
|
|
|
|
|
+ :mobileBreakpoint="1024"
|
|
|
|
|
+ mobileHeader="Навигация"
|
|
|
|
|
+ :showMobileHeader="true"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Интеграция с системой прав доступа
|
|
|
|
|
+
|
|
|
|
|
+### Фильтрация меню по правам
|
|
|
|
|
+```coffee
|
|
|
|
|
+computed:
|
|
|
|
|
+ filteredMenu: ->
|
|
|
|
|
+ userPermissions = @$store.state.user.permissions
|
|
|
|
|
+ return @filterMenuByPermissions(@menuData, userPermissions)
|
|
|
|
|
+
|
|
|
|
|
+methods:
|
|
|
|
|
+ filterMenuByPermissions: (menuItems, permissions) ->
|
|
|
|
|
+ return menuItems.filter (item) =>
|
|
|
|
|
+ if item.permissions
|
|
|
|
|
+ return item.permissions.some (perm) -> permissions.includes(perm)
|
|
|
|
|
+ return true
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Best Practices
|
|
|
|
|
+
|
|
|
|
|
+### 1. Оптимизация структуры данных
|
|
|
|
|
+```coffee
|
|
|
|
|
+# Правильно - плоская структура с ссылками на детей
|
|
|
|
|
+menuData = [
|
|
|
|
|
+ { id: 'parent', title: 'Родитель', url: '/parent' },
|
|
|
|
|
+ { id: 'child', title: 'Ребенок', url: '/child', parentId: 'parent' }
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+# Неправильно - глубоко вложенные объекты
|
|
|
|
|
+menuData = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title: 'Родитель',
|
|
|
|
|
+ children: [
|
|
|
|
|
+ { title: 'Ребенок', children: [...] }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 2. Использование мультиязычных массивов
|
|
|
|
|
+```coffee
|
|
|
|
|
+menuItem =
|
|
|
|
|
+ title: ['Русский текст', 'English text', 'Тоҷикӣ матн']
|
|
|
|
|
+ # Компонент автоматически выберет нужный язык
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. Правильная обработка событий
|
|
|
|
|
+```coffee
|
|
|
|
|
+methods:
|
|
|
|
|
+ handleMenuClick: ({ item, event, level }) ->
|
|
|
|
|
+ # Предотвращаем переход для специальных пунктов
|
|
|
|
|
+ if item.type is 'button'
|
|
|
|
|
+ event.preventDefault()
|
|
|
|
|
+ @handleButtonAction(item)
|
|
|
|
|
+
|
|
|
|
|
+ # Логируем навигацию
|
|
|
|
|
+ analytics.track('menu_click', {
|
|
|
|
|
+ item: item.id,
|
|
|
|
|
+ level: level
|
|
|
|
|
+ })
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4. Оптимизация производительности
|
|
|
|
|
+```pug
|
|
|
|
|
+<!-- Правильно - стабильные ID -->
|
|
|
|
|
+multilevelmenu(:menuItems="menuData" :key="menuVersion")
|
|
|
|
|
+
|
|
|
|
|
+<!-- Неправильно - изменяемые ID -->
|
|
|
|
|
+multilevelmenu(:menuItems="dynamicMenu")
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Отладка и разработка
|
|
|
|
|
+
|
|
|
|
|
+### Включение режима отладки
|
|
|
|
|
+```pug
|
|
|
|
|
+multilevelmenu(
|
|
|
|
|
+ :menuItems="menuData"
|
|
|
|
|
+ debug
|
|
|
|
|
+ @item-click="console.log"
|
|
|
|
|
+ @menu-open="console.log"
|
|
|
|
|
+)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Проверка состояния меню
|
|
|
|
|
+```coffee
|
|
|
|
|
+# В консоли разработчика
|
|
|
|
|
+$refs.menu.getActiveItem()
|
|
|
|
|
+$refs.menu.getMenuPath('item-id')
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Компонент MultiLevelMenu предоставляет мощный и гибкий инструмент для создания сложных навигационных систем с поддержкой многоуровневой структуры, адаптивным дизайном и расширенными возможностями кастомизации.
|