|
@@ -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 предоставляет богатый функционал для создания адаптивных, доступных и производительных слайдеров с полной поддержкой мультиязычности и кастомизации.
|