Gogs il y a 3 semaines
Parent
commit
c39f03b2fa
2 fichiers modifiés avec 462 ajouts et 2 suppressions
  1. 2 2
      README.md
  2. 460 0
      vue/app/shared/ImageSlider/README.md

+ 2 - 2
README.md

@@ -1,6 +1,6 @@
 # Текущая задача
-Опиши компонент для возможности использования в разработке: https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master/vue/app/shared/ImageSlider
-сделай полное описание вех методобов использования и взаимодействия. 
+Опиши компонент для возможности использования в разработке: https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master/vue/app/shared/MultiLevelMenu
+сделай полное описание вех методов использования и взаимодействия. (в описание не дублируй листинги из репозитария)
 
 # файл с правилами
 https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/raw/master/README.md

+ 460 - 0
vue/app/shared/ImageSlider/README.md

@@ -0,0 +1,460 @@
+# Компонент ImageSlider - Полная документация
+
+## Назначение компонента
+
+`ImageSlider` - универсальный компонент для создания слайдеров изображений с поддержкой автоматической прокрутки, ручного управления, индикаторов и адаптивного дизайна. Компонент оптимизирован для работы с мультиязычным контентом и поддерживает различные типы медиа-контента.
+
+## Импорт и регистрация
+
+```coffee
+# В основном файле приложения (app/temp.coffee)
+components:
+    'imageslider': require 'app/shared/ImageSlider'
+```
+
+## Базовое использование
+
+### 1. Простой слайдер с изображениями
+```pug
+imageslider(:slides="slides")
+```
+
+### 2. Слайдер с кастомными настройками
+```pug
+imageslider(
+    :slides="featuredSlides"
+    :autoplay="true"
+    :interval="5000"
+    :show-indicators="true"
+    :show-controls="true"
+)
+```
+
+## Полный список props
+
+### `slides` (обязательный)
+- **Тип:** `Array`
+- **Описание:** Массив объектов слайдов
+- **Структура слайда:**
+  ```coffee
+  {
+    _id: String
+    type: 'slide'
+    title: Array[String]        # Мультиязычные заголовки
+    content: Array[String]      # Мультиязычный контент
+    image: Array[String]        # Мультиязычные пути к изображениям
+    slide_data: {
+      order: Number
+      active: Boolean
+      button_text: Array[String]
+      button_link: Array[String]
+      button_style: String
+      text_color: Array[String]
+      text_position: Array[String]
+      overlay: Array[Boolean]
+      overlay_opacity: Array[Number]
+    }
+  }
+  ```
+
+### `autoplay` (опциональный)
+- **Тип:** `Boolean`
+- **По умолчанию:** `true`
+- **Описание:** Автоматическая прокрутка слайдов
+
+### `interval` (опциональный)
+- **Тип:** `Number`
+- **По умолчанию:** `4000`
+- **Описание:** Интервал автоматической прокрутки в миллисекундах
+
+### `showIndicators` (опциональный)
+- **Тип:** `Boolean`
+- **По умолчанию:** `true`
+- **Описание:** Показывать индикаторы слайдов
+
+### `showControls` (опциональный)
+- **Тип:** `Boolean`
+- **По умолчанию:** `true`
+- **Описание:** Показывать кнопки управления (вперед/назад)
+
+### `height` (опциональный)
+- **Тип:** `String`
+- **По умолчанию:** `'400px'`
+- **Описание:** Высота слайдера (CSS значение)
+
+### `transition` (опциональный)
+- **Тип:** `String`
+- **По умолчанию:** `'slide'`
+- **Допустимые значения:** `'slide'`, `'fade'`
+- **Описание:** Тип анимации перехода между слайдами
+
+## События (Events)
+
+### `@slide-change`
+- **Описание:** Событие смены слайда
+- **Payload:** `{ currentSlide: Object, index: Number }`
+- **Пример:**
+  ```pug
+  imageslider(:slides="slides" @slide-change="onSlideChange")
+  ```
+
+### `@slide-click`
+- **Описание:** Событие клика по слайду
+- **Payload:** `{ slide: Object, index: Number }`
+- **Пример:**
+  ```pug
+  imageslider(:slides="slides" @slide-click="onSlideClick")
+  ```
+
+## Слоты (Slots)
+
+### `[slide]` (кастомный контент слайда)
+- **Описание:** Слот для кастомного отображения слайда
+- **Props:** `{ slide: Object, index: Number, active: Boolean }`
+- **Пример:**
+  ```pug
+  imageslider(:slides="slides")
+      template([slide]="{ slide, index, active }")
+          div(class="relative h-full flex items-center justify-center")
+              img(:src="slide.image" :alt="slide.title" class="w-full h-full object-cover")
+              div(v-if="active" class="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center")
+                  h2(class="text-white text-4xl font-bold") {{ slide.title }}
+  ```
+
+### `[indicators]` (кастомные индикаторы)
+- **Описание:** Слот для кастомных индикаторов
+- **Props:** `{ slides: Array, currentIndex: Number, goToSlide: Function }`
+- **Пример:**
+  ```pug
+  imageslider(:slides="slides")
+      template([indicators]="{ slides, currentIndex, goToSlide }")
+          div(class="flex space-x-2 absolute bottom-4 left-1/2 transform -translate-x-1/2")
+              button(
+                  v-for="(slide, index) in slides"
+                  :key="slide._id"
+                  @click="goToSlide(index)"
+                  :class="currentIndex === index ? 'bg-white' : 'bg-white bg-opacity-50'"
+                  class="w-3 h-3 rounded-full transition-all"
+              )
+  ```
+
+### `[controls]` (кастомные кнопки управления)
+- **Описание:** Слот для кастомных кнопок управления
+- **Props:** `{ nextSlide: Function, prevSlide: Function }`
+- **Пример:**
+  ```pug
+  imageslider(:slides="slides")
+      template([controls]="{ nextSlide, prevSlide }")
+          div(class="absolute inset-y-0 left-0 flex items-center")
+              button(@click="prevSlide" class="ml-4 p-2 bg-black bg-opacity-50 text-white rounded-full")
+                  icon(name="chevron-left")
+          div(class="absolute inset-y-0 right-0 flex items-center")
+              button(@click="nextSlide" class="mr-4 p-2 bg-black bg-opacity-50 text-white rounded-full")
+                  icon(name="chevron-right")
+  ```
+
+## Методы компонента
+
+### `nextSlide()`
+- **Описание:** Переход к следующему слайду
+- **Пример использования:**
+  ```pug
+  imageslider(ref="slider" :slides="slides")
+  ```
+  ```coffee
+  @$refs.slider.nextSlide()
+  ```
+
+### `prevSlide()`
+- **Описание:** Переход к предыдущему слайду
+- **Пример использования:**
+  ```coffee
+  @$refs.slider.prevSlide()
+  ```
+
+### `goToSlide(index)`
+- **Описание:** Переход к конкретному слайду по индексу
+- **Параметры:** `index: Number`
+- **Пример использования:**
+  ```coffee
+  @$refs.slider.goToSlide(2) # Переход к третьему слайду
+  ```
+
+### `play()`
+- **Описание:** Запуск автоматической прокрутки
+- **Пример использования:**
+  ```coffee
+  @$refs.slider.play()
+  ```
+
+### `pause()`
+- **Описание:** Приостановка автоматической прокрутки
+- **Пример использования:**
+  ```coffee
+  @$refs.slider.pause()
+  ```
+
+## Примеры использования в различных сценариях
+
+### 1. Главный слайдер на homepage
+```pug
+imageslider(
+    :slides="_.appState.slides"
+    :autoplay="true"
+    :interval="5000"
+    :height="'600px'"
+    :show-indicators="true"
+    :show-controls="true"
+    @slide-change="trackSlideView"
+    class="rounded-lg shadow-xl"
+)
+```
+
+### 2. Слайдер мероприятий с кастомным контентом
+```pug
+imageslider(
+    :slides="eventSlides"
+    :autoplay="false"
+    :show-indicators="false"
+    class="event-slider"
+)
+    template([slide]="{ slide, index, active }")
+        div(class="relative h-80 rounded-lg overflow-hidden shadow-lg")
+            img(
+                :src="getText(slide.image)" 
+                :alt="getText(slide.title)"
+                class="w-full h-full object-cover"
+            )
+            div(class="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent flex items-end")
+                div(class="p-6 text-white")
+                    h3(class="text-xl font-bold mb-2") {{ getText(slide.title) }}
+                    p(class="text-gray-200 mb-4") {{ getText(slide.content) }}
+                    app-link(
+                        :to="getText(slide.slide_data.button_link)"
+                        class="inline-block bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors"
+                    ) {{ getText(slide.slide_data.button_text) }}
+```
+
+### 3. Мини-слайдер товаров
+```pug
+imageslider(
+    :slides="productSlides"
+    :height="'300px'"
+    :show-controls="false"
+    :autoplay="true"
+    :interval="3000"
+    class="product-slider"
+)
+    template([indicators]="{ slides, currentIndex, goToSlide }")
+        div(class="flex justify-center space-x-1 mt-4")
+            button(
+                v-for="(slide, index) in slides"
+                :key="slide._id"
+                @click="goToSlide(index)"
+                :class="currentIndex === index ? 'w-8 bg-blue-600' : 'w-2 bg-gray-300'"
+                class="h-2 rounded-full transition-all duration-300"
+            )
+```
+
+### 4. Fullscreen слайдер галереи
+```pug
+imageslider(
+    :slides="gallerySlides"
+    :autoplay="false"
+    :transition="'fade'"
+    :height="'100vh'"
+    class="gallery-slider"
+)
+    template([controls]="{ nextSlide, prevSlide }")
+        div(class="absolute inset-0 flex items-center justify-between pointer-events-none")
+            button(
+                @click="prevSlide"
+                class="pointer-events-auto ml-8 p-4 bg-black bg-opacity-50 text-white rounded-full hover:bg-opacity-70 transition-opacity"
+            )
+                icon(name="arrow-left" class="w-6 h-6")
+            button(
+                @click="nextSlide"
+                class="pointer-events-auto mr-8 p-4 bg-black bg-opacity-50 text-white rounded-full hover:bg-opacity-70 transition-opacity"
+            )
+                icon(name="arrow-right" class="w-6 h-6")
+```
+
+### 5. Слайдер с текстовым оверлеем
+```pug
+imageslider(:slides="slidesWithOverlay")
+    template([slide]="{ slide, active }")
+        div(class="relative h-full")
+            img(
+                :src="getText(slide.image)"
+                :alt="getText(slide.title)"
+                class="w-full h-full object-cover"
+            )
+            div(
+                v-if="slide.slide_data.overlay"
+                :style="{
+                    backgroundColor: 'rgba(0,0,0,' + (slide.slide_data.overlay_opacity || 0.4) + ')'
+                }"
+                class="absolute inset-0 flex items-center justify-center"
+            )
+                div(
+                    :class="'text-' + (getText(slide.slide_data.text_position) || 'center')"
+                    :style="{ color: getText(slide.slide_data.text_color) || '#ffffff' }"
+                    class="max-w-2xl px-8"
+                )
+                    h2(class="text-4xl font-bold mb-4") {{ getText(slide.title) }}
+                    p(class="text-xl mb-6") {{ getText(slide.content) }}
+                    app-link(
+                        v-if="getText(slide.slide_data.button_text)"
+                        :to="getText(slide.slide_data.button_link)"
+                        :class="getButtonStyle(slide.slide_data.button_style)"
+                        class="inline-block px-8 py-3 rounded-lg font-semibold transition-colors"
+                    ) {{ getText(slide.slide_data.button_text) }}
+```
+
+## Интеграция с мультиязычной системой
+
+### Использование с MultilingualData
+```pug
+imageslider(:slides="multilingualSlides")
+    template([slide]="{ slide }")
+        div(class="relative h-full")
+            img(
+                :src="AppDB.multilingual.getText(slide.image)"
+                :alt="AppDB.multilingual.getText(slide.title)"
+                class="w-full h-full object-cover"
+            )
+            div(class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black to-transparent p-6")
+                h3(class="text-white text-2xl font-bold mb-2") 
+                    | {{ AppDB.multilingual.getText(slide.title) }}
+                p(class="text-gray-200") 
+                    | {{ AppDB.multilingual.getText(slide.content) }}
+```
+
+## Обработка событий
+
+### Отслеживание просмотров слайдов
+```coffee
+methods:
+    onSlideChange: (data) ->
+        # data: { currentSlide: Object, index: Number }
+        analytics.track('slide_view', {
+            slide_id: data.currentSlide._id
+            slide_index: data.index
+            slide_title: AppDB.multilingual.getText(data.currentSlide.title)
+        })
+    
+    onSlideClick: (data) ->
+        # data: { slide: Object, index: Number }
+        if data.slide.slide_data?.button_link
+            EventBus.emit('slide_button_click', {
+                slide: data.slide
+                button_text: AppDB.multilingual.getText(data.slide.slide_data.button_text)
+                button_link: AppDB.multilingual.getText(data.slide.slide_data.button_link)
+            })
+```
+
+## Кастомизация стилей
+
+### CSS переменные для кастомизации
+```styl
+.image-slider
+    --slider-height: 400px
+    --slider-transition-duration: 0.5s
+    --indicator-size: 12px
+    --indicator-active-color: #3B82F6
+    --indicator-inactive-color: #9CA3AF
+    --control-size: 48px
+    --control-bg: rgba(0, 0, 0, 0.5)
+    --control-color: #FFFFFF
+```
+
+### Кастомные темы
+```styl
+// Темная тема
+.image-slider--dark
+    --indicator-active-color: #60A5FA
+    --indicator-inactive-color: #4B5563
+    --control-bg: rgba(255, 255, 255, 0.1)
+    --control-color: #F9FAFB
+
+// Минималистичная тема
+.image-slider--minimal
+    --indicator-size: 8px
+    --control-size: 40px
+    --control-bg: transparent
+    --control-color: #1F2937
+    
+    .image-slider__control
+        border: 1px solid #E5E7EB
+```
+
+## Best Practices
+
+### 1. Оптимизация изображений
+```pug
+imageslider(:slides="optimizedSlides")
+    template([slide]="{ slide }")
+        div(class="relative h-full")
+            img(
+                :src="getOptimizedImage(slide.image)"
+                :alt="getText(slide.title)"
+                loading="lazy"
+                class="w-full h-full object-cover"
+            )
+```
+
+### 2. Обработка ошибок загрузки
+```pug
+imageslider(:slides="slides")
+    template([slide]="{ slide }")
+        div(class="relative h-full")
+            img(
+                :src="getText(slide.image)"
+                :alt="getText(slide.title)"
+                @error="handleImageError"
+                class="w-full h-full object-cover"
+            )
+```
+
+### 3. Доступность (Accessibility)
+```pug
+imageslider(
+    :slides="slides"
+    aria-label="Галерея изображений"
+    role="region"
+)
+```
+
+### 4. Производительность
+```pug
+imageslider(
+    :slides="lazyLoadedSlides"
+    :autoplay="isVisible"
+    @slide-change="preloadNextSlide"
+)
+```
+
+## Отладка и разработка
+
+### Логирование состояния
+```coffee
+# В родительском компоненте
+mounted: ->
+    EventBus.on 'slide_change', (data) ->
+        debug.log "Слайд изменен: "+data.index
+        
+    EventBus.on 'slider_autoplay_status', (data) ->
+        debug.log "Автопрокрутка: "+(data.playing ? 'включена' : 'выключена')
+```
+
+### Валидация данных слайдов
+```coffee
+computed:
+    validatedSlides: ->
+        return @slides.filter (slide) ->
+            slide.image? and 
+            slide.image.length > 0 and
+            slide.slide_data?.active isnt false
+```
+
+Компонент ImageSlider предоставляет богатый функционал для создания адаптивных, доступных и производительных слайдеров с полной поддержкой мультиязычности и кастомизации.