Олег Марков
Использование Swiper для создания слайдеров в Vue
Введение
Слайдеры давно стали неотъемлемой частью современных веб-приложений. Они позволяют лаконично и эффективно отображать галереи изображений, карусели отзывов, новостные ленты, анимации товаров и многое другое. Среди различных инструментов для создания слайдеров на фронтенде, библиотека Swiper выделяется богатым функционалом, гибкими настройками и отличной совместимостью с их интеграцией во Vue-приложения любого уровня сложности.
В этой статье я покажу вам, как использовать Swiper для создания слайдеров в Vue, обсудим основные методы и возможности библиотеки. Практические примеры, подробные комментарии и разбор решений популярных задач помогут вам внедрить Swiper в свои проекты быстро и без лишних сложностей.
Установка и подключение Swiper в проект Vue
Для начала рассмотрим, как подключить Swiper к вашему Vue-проекту. Допустим, у вас уже есть базовый проект Vue, например, созданный с помощью Vue CLI или Vite.
Установка пакета Swiper
Выполняем в терминале:
npm install swiper
или, если вы используете Yarn:
bash
yarn add swiper
Импорт стилей Swiper
Стили обязательно нужно добавить на уровень компонента или глобально в проекте. Обычно проще всего импортировать их непосредственно в компоненте или вашем основном файле стилей.
Например, в main.js
или main.ts
:
js
import 'swiper/swiper-bundle.css' // импорт основных стилей Swiper
Или если вы хотите подключить только базовые стили:
js
import 'swiper/css'
Интеграция Swiper во Vue-компонент
В версии Swiper 7+ специально для Vue2 и Vue3 предоставляются отдельные компоненты:
swiper/vue
— для Vue 3swiper/vue/swiper-vue
— для Vue 2 (только для версии 6.x Swiper)
Сфокусируемся на Vue 3 (аналогичные действия выполняются для Vue 2, только синтаксис импортов чуть отличается).
Пример подключения компонентов:
<template>
<Swiper
:modules="[Navigation, Pagination]"
:slides-per-view="1"
:space-between="20"
navigation
pagination
>
<SwiperSlide v-for="(slide, idx) in slides" :key="idx">
{{ slide.text }}
</SwiperSlide>
</Swiper>
</template>
<script setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Navigation, Pagination } from 'swiper'
// Не забудьте про стили!
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
const slides = [
{ text: 'Слайд 1' },
{ text: 'Слайд 2' },
{ text: 'Слайд 3' }
]
</script>
В этом примере я показываю вам минимальный конфиг: указываю, какие модули подключаю (Navigation
, Pagination
), как они инициализируются, и как обрабатываются элементы слайдов.
Основные возможности и методы Swiper
Swiper предлагает широкий набор возможностей, которые можно гибко конфигурировать. Давайте разберем самые популярные и нужные из них.
Навигация: стрелки и пагинация
Навигация добавляет стрелки вперед/назад, а пагинация — точки или прогресс-бар для обозначения текущего положения в слайдере.
<template>
<Swiper
:modules="[Navigation, Pagination]"
navigation
pagination
>
...
</Swiper>
</template>
navigation
отвечает за добавление стрелок.pagination
— за точки-пагинаторы.
Swiper автоматически вставляет необходимые элементы стрелок и пагинации, если не настраивать их кастомно.
Автоматическое пролистывание (autoplay)
Если вам нужен автоматический показ слайдов с определенной задержкой (например, для промо-баннера или отзывов), включайте опцию autoplay
.
<template>
<Swiper
:modules="[Autoplay, Pagination]"
:autoplay="{ delay: 2500, disableOnInteraction: false }"
pagination
>
...
</Swiper>
</template>
<script setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Autoplay, Pagination } from 'swiper'
import 'swiper/css'
import 'swiper/css/pagination'
</script>
delay
— задержка между сменой слайдов, в миллисекундах.disableOnInteraction
— флаг: останавливаться ли автопрокрутке, если пользователь взаимодействовал со слайдером (полезно для интерактивных галерей).
Адаптивность: slidesPerView и breakpoints
Иногда требуется показывать разное количество слайдов на разных экранах (мобильные, планшеты, десктоп).
Swiper предлагает свойство breakpoints
:
<Swiper
:modules="[Navigation]"
:slides-per-view="1"
:breakpoints="{
640: { slidesPerView: 2, spaceBetween: 10 },
1024: { slidesPerView: 3, spaceBetween: 20 }
}"
navigation
>
...
</Swiper>
Здесь я показываю вам, как передать объект с ключами — это ширина окна в px, а значения — объект с настройками.
Ручное управление через события и методы
Вы часто встретите задачи: получить текущий слайд, программно переключить на нужный слайд, остановить или запустить autoplay. Для этого есть события и публичные методы Swiper.
Работа с текущим слайдом
Вы можете повесить слушатель на событие slideChange
:
<Swiper
@slideChange="onSlideChange"
>
...
</Swiper>
function onSlideChange(swiper) {
// swiper.activeIndex — индекс текущего слайда
console.log('Новый активный слайд:', swiper.activeIndex)
}
Программное переключение слайдов
В Vue 3 отлично работают ссылки (ref
) на компоненты. Давайте добавим пример:
<template>
<Swiper ref="mySwiper">
...
</Swiper>
<button @click="slideToNext">Следующий слайд</button>
</template>
<script setup>
import { ref } from 'vue'
import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'
const mySwiper = ref(null)
function slideToNext() {
// Переходим к следующему слайду
mySwiper.value.swiper.slideNext()
}
</script>
Обратите внимание, что обращение к API происходит через ref.value.swiper
.
Кастомизация контента слайдов
Вам не обязательно использовать только изображения — внутри <SwiperSlide>
можно размещать любые компоненты или разметку. Например, карточки товаров, отзывы, формы.
<Swiper>
<SwiperSlide>
<ProductCard :data="product1" />
</SwiperSlide>
<SwiperSlide>
<ProductCard :data="product2" />
</SwiperSlide>
</Swiper>
Здесь <ProductCard>
— ваш собственный компонент.
Асинхронная загрузка и динамические слайды
Если данные для слайдера приходят по API, вам не нужно хитро обновлять Swiper — достаточно передать им получившийся массив данных:
<Swiper>
<SwiperSlide v-for="item in asyncSlides" :key="item.id">
{{ item.text }}
</SwiperSlide>
</Swiper>
Swiper корректно реагирует на изменение массива через reactivity Vue.
Ленивая загрузка изображений (lazy loading)
В сочетании со Swiper здорово работает ленивое подгружание тяжелых картинок. Используйте модуль Lazy
:
<Swiper
:modules="[Lazy]"
lazy="true"
>
<SwiperSlide v-for="img in images" :key="img.id">
<img
:data-src="img.src" // используем data-src вместо src
class="swiper-lazy"
:alt="img.alt"
/>
<div class="swiper-lazy-preloader"></div>
</SwiperSlide>
</Swiper>
swiper-lazy
— специальный css-класс для Swiper.- Обратите внимание, здесь указывается
data-src
, самsrc
не прописывается.
Глобальные и локальные стили для Swiper
Чтобы Swiper корректно отображался, ему нужны стили. Вы можете:
- оставить стандартные стили (import 'swiper/css' и пр. в компоненте или main.js)
- добавить свои стили для кастомизации стрелок, пагинации, скролл-баров
Пример стилизации кнопок навигации:
.swiper-button-next,
.swiper-button-prev {
color: #2d5aef; /* делаем стрелки синими */
width: 40px;
height: 40px;
background: rgba(0,0,0,.1);
border-radius: 50%;
}
Продвинутые возможности Swiper во Vue
Swiper умеет больше, чем кажется на первый взгляд. Посмотрим, как добавить необычные эффекты, адаптировать под SSR и создать уникальный пользовательский опыт.
Эффекты переходов между слайдами
Вы можете выбрать эффект перелистывания: fade, cube, coverflow, flip и другие.
Пример fade-эффекта:
<Swiper
:modules="[EffectFade]"
effect="fade"
:fadeEffect="{ crossFade: true }"
>
...
</Swiper>
Не забудьте подключить css стили (import 'swiper/css/effect-fade').
Два слайдера, связанные между собой
Swiper позволяет делать синхронизированные слайдеры, например, один для главного изображения, второй — превью.
<template>
<Swiper
ref="galleryTop"
:modules="[Thumbs]"
:thumbs="{ swiper: galleryThumbs }"
>
<SwiperSlide v-for="img in images" :key="img.id">
<img :src="img.src" />
</SwiperSlide>
</Swiper>
<Swiper
ref="galleryThumbs"
:modules="[Thumbs]"
:slides-per-view="4"
watch-slides-progress
>
<SwiperSlide v-for="img in images" :key="img.id">
<img :src="img.thumb" />
</SwiperSlide>
</Swiper>
</template>
<script setup>
import { ref } from 'vue'
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Thumbs } from 'swiper'
import 'swiper/css'
import 'swiper/css/thumbs'
const galleryTop = ref(null)
const galleryThumbs = ref(null)
const images = [
{ id: 1, src: 'big1.jpg', thumb: 'thumb1.jpg' },
{ id: 2, src: 'big2.jpg', thumb: 'thumb2.jpg' }
]
</script>
Использование с SSR (Nuxt, Vue + SSR)
Чтобы избежать ошибок на стороне сервера (когда нет объекта window), оборачивайте инициализацию Swiper в проверку наличия window или рендерите Swiper только на клиенте:
<template>
<ClientOnly>
<Swiper ... />
</ClientOnly>
</template>
Где <ClientOnly>
— компонент Nuxt или аналогичный компонент для вашего SSR фреймворка. Это предотвратит проблемы несоответствия html между сервером и клиентом.
Динамическое управление параметрами
Настройки слайдера можно делать реактивными:
<script setup>
import { ref, watch } from 'vue'
// ...
const slidesPerView = ref(1)
watch(windowWidth, newVal => {
slidesPerView.value = newVal > 900 ? 3 : 1
})
</script>
<Swiper :slides-per-view="slidesPerView" ...>
...
</Swiper>
Это удобно, если хотите динамически менять параметры слайдера при изменении состояния приложения.
Заключение
Использование Swiper во Vue-проектах — это удобный способ добавить современные, адаптивные и производительные слайдеры с множеством кастомизаций. Библиотека отлично вписывается как в малы проекты, так и в крупные корпоративные интерфейсы. Ее простой API, масса событий и продвинутых настроек позволят создать слайдер под любые нужды: от элементарной галереи до сложных интерактивных блоков. Рекомендую изучить документацию Swiper для более глубокой кастомизации и изучить дополнительные модули для расширения возможностей слайдера в Vue.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как избавиться от ошибки "Can't find variable: window" при использовании Swiper с SSR?
Эта ошибка возникает из-за попытки использовать Swiper на сервере, где объект window
отсутствует. Решение: используйте Swiper только на клиенте, обернув компонент в <client-only>
(Nuxt) или аналогичный компонент своего фреймворка, чтобы слайдер рендерился только в браузере.
Как сделать кастомные кнопки навигации, а не стандартные от Swiper?
Вы можете рендерить свои элементы-кнопки вне слайдера и передавать в Swiper ссылки на них через параметры navigation: { nextEl, prevEl }
. Для этого добавьте свои кнопки в шаблон, присвойте им классы или ref
, затем используйте соответствующие параметры в компоненте Swiper.
Почему слайды Swiper не обновляются после изменения данных во Vue?
Если вы асинхронно обновляете массив слайдов, Swiper может не зафиксировать изменения. Решение: убедитесь, что массив слайдов меняется реактивно (v-for
с ключами), и используйте метод Swiper swiper.update()
, вызываемый через ref вручную после изменения данных (к примеру, после загрузки изображений асинхронно).
Как подгрузить больше слайдов при прокрутке пользователя (бесконечная прокрутка / infinite scroll)?
Вы можете использовать событие reachEnd
Swiper, чтобы по достижении конца подгрузить новые данные:js
function onReachEnd() {
// Асинхронно добавьте новые данные в массив слайдов
}
Просто подпишитесь на это событие через @reachEnd="onReachEnd"
в Swiper.
Можно ли использовать Swiper со сторонними UI библиотеками (например, Vuetify, Element Plus)?
Да, Swiper отлично работает с любыми UI-библиотеками, если вы размещаете его внутри их компонентов/гридов. Главное, не забывайте добавлять стили Swiper после стилей сторонней библиотеки, чтобы не возникало конфликтов CSS. Также учитывайте, что для корректной работы модулей и кастомных кнопок, возможно потребуется ручная интеграция (как указано выше).