Розробка слайдерів і каруселей на Vue.js для 1С-Бітрікс
На більшості бітриксових проєктів слайдери реалізовані через Swiper.js із jQuery-ініціалізацією в template.php. Це працює для простих випадків. Проблеми починаються, коли потрібно: динамічно підвантажувати слайди з кошика або обраного, синхронізувати кілька каруселей (головна + мініатюри), керувати станом активного слайда з іншого компонента. Vue.js дає реактивність, якої в jQuery немає за визначенням.
Чому Vue, а не чистий Swiper у Бітрікс
Swiper.js — відмінна бібліотека для статичного контенту. Але коли слайдер пов'язаний із даними — кошик, wishlist, фільтри каталогу — jQuery-підхід вимагає ручної синхронізації DOM і стану. Додав товар в обране → потрібно викликати swiper.update(), перерахувати слайди, оновити лічильник. При помилці AJAX — відкатити візуальний стан вручну.
Vue вирішує це через реактивність: масив слайдів у ref() — джерело правди. Змінився масив — Vue перемалював DOM. Swiper (якщо потрібні його жести) монтується поверх уже готового Vue-рендеру через onMounted.
Основні патерни інтеграції:
-
Vue + нативний Swiper — Vue керує даними, Swiper додає тач-жести та переходи. Ініціалізація Swiper в
onMounted, знищення вonBeforeUnmount, перестворення при зміні масиву черезwatch -
Повністю на Vue — для каруселей без складної фізики (товари, відгуки, банери). CSS-transitions +
transform: translateX()через обчислені стилі. Менше залежностей, повний контроль - vue3-carousel — готова бібліотека, добре типізована, підтримує infinite loop, autoplay, responsive breakpoints. Для типових задач позбавляє від написання логіки переходів
Типові сценарії для Бітрікс
Головний банер із контентом з інфоблоку. Слайди беруться з CIBlockElement::GetList у result_modifier.php, передаються у Vue через data-slides JSON або через window.BX_STATE. Автоплей, пауза при hover, лічильник слайдів, навігація крапками та стрілками.
Карусель товарів (хіти, новинки, схожі товари). Дані з bitrix:catalog.section або через REST /bitrix/api.php. Картка товару — вкладений Vue-компонент із кнопкою «До кошика», яка оновлює cartStore через Pinia. Зміна стану кнопки (додається → додано) без перезавантаження сторінки.
Галерея товару з синхронізацією. Два пов'язаних слайдери: великі зображення + смуга мініатюр. При кліку на мініатюру — основний слайдер переходить до потрібного зображення. Через provide/inject або через Pinia — один activeIndex на обидва компоненти. Масштабування по кліку (zoom) через CSS transform без окремої бібліотеки.
Слайдер відгуків. Контент з інфоблоку «Відгуки», lazy-load зображень аватарів через IntersectionObserver. Нескінченна прокрутка — при досягненні кінця масив клонується в реактивному computed.
Кейс: синхронізована галерея із зумом для картки товару
Інтернет-магазин меблів, 15–40 фотографій на товар, вимога: основне зображення + смуга мініатюр + зум при наведенні + підтримка свайпу на мобільних.
Стандартний бітриксовий компонент bitrix:catalog.element виводив єдине зображення без галереї. Додавання jQuery-lightbox створювало конфлікти зі Swiper, який вже використовувався для схожих товарів.
Рішення: Vue-компонент ProductGallery, монтується на #product-gallery-root. Дані зображень передаються через window.BX_STATE.gallery — масив об'єктів {thumb, full, alt}, сформованих у PHP із CIBlockElement::GetList із вибіркою DETAIL_PICTURE і MORE_PHOTO.
// Синхронізація через один реактивний індекс
const activeIndex = ref(0);
// Зум через CSS custom properties
const zoomStyle = computed(() => ({
'--zoom-x': `${zoomPos.x}%`,
'--zoom-y': `${zoomPos.y}%`
}));
Свайп на мобільних — через @vueuse/core useSwipe. Перехід між зображеннями — CSS opacity transition 200ms. Мініатюри — горизонтальний скрол через scrollIntoView при зміні activeIndex. Зум при hover — CSS transform: scale(2) із transform-origin за позицією миші через mousemove-обробник.
Підсумок: одна залежність (@vueuse/core), 280 рядків коду, повна заміна трьох jQuery-плагінів. Час завантаження сторінки не змінився — бандл 18 КБ gzipped підключається лише на сторінці товару.
Збірка та підключення у Бітрікс
Слайдери — ізольовані Vue-застосунки, кожен монтується на свій кореневий елемент. Vite збирає окремі точки входу для кожного компонента:
// vite.config.js
export default {
build: {
rollupOptions: {
input: {
productGallery: 'src/product-gallery/main.js',
homeBanner: 'src/home-banner/main.js',
reviewsSlider: 'src/reviews-slider/main.js',
}
}
}
}
Підключення через \Bitrix\Main\Page\Asset лише на потрібних сторінках. Компоненти не знають один про одного, конфлікти виключені. Якщо Pinia потрібна в кількох компонентах на одній сторінці — створюється один глобальний store, підключається як singleton через window.__pinia.
Етапи та терміни
| Тип слайдера | Орієнтовний термін |
|---|---|
| Банер із контентом з інфоблоку | 1-2 дні |
| Карусель товарів із кошиком | 2-4 дні |
| Синхронізована галерея із зумом | 3-6 днів |
| Комплекс із 3-4 пов'язаних слайдерів | 5-10 днів |
Терміни збільшуються при нестандартних анімаціях, складних breakpoints та вимогах до accessibility (ARIA live regions для screen readers).







