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