Розробка табів та акордеонів на Vue.js для 1С-Бітрікс — архітектурне рішення, яке безпосередньо впливає на продуктивність, SEO-індексацію та UX. Неправильний підхід призводить до дублювання HTML, уповільнення завантаження та неможливості глибоких посилань. Ми створюємо компоненти, які економлять до 30% часу розробки та скорочують HTML-код у 2-3 рази.
У стандартному бітріксовому шаблоні з 5 вкладками в DOM рендериться в 5 разів більше контенту, ніж потрібно — це збільшує час завантаження на 200–500 мс на мобільних пристроях. jQuery-реалізації через .show()/.hide() не оновлюють URL, що робить неможливим глибоке посилання на вкладку. Наш стек — Vue.js, PHP 8.1+, інфоблоки v2.0, теговане кешування. Ми спеціалізуємося на цій зв'язці понад 6 років і реалізували 45+ проектів з кастомними інтерфейсами.
Як реалізувати ліниве завантаження вкладок?
Таби будуються на парі компонентів: TabGroup керує активним станом, TabPanel рендерить вміст активної вкладки. Ключове рішення — як зберігати активний таб:
- ref() всередині компонента — якщо URL не потрібен
- useRoute з Vue Router — для SPA-сторінок з повним роутингом
- URLSearchParams через нативний history.pushState — для сторінок Бітрікса без Vue Router, коли потрібне глибоке посилання
// Збереження активного таба в URL без Vue Router const activeTab = ref(new URLSearchParams(location.search).get('tab') || 'description'); watch(activeTab, (tab) => { const url = new URL(location.href); url.searchParams.set('tab', tab); history.replaceState({}, '', url); }); Це дозволяє користувачу скопіювати посилання на конкретну вкладку — критично для карток товарів з вкладками «Характеристики», «Відгуки», «Доставка».
Акордеони вимагають плавної анімації висоти, що нетривіально в CSS: height: auto не анімується. Рішення через Vue <Transition> з JavaScript hooks:
function onEnter(el) { el.style.height = '0'; el.offsetHeight; // force reflow el.style.height = el.scrollHeight + 'px'; } function onAfterEnter(el) { el.style.height = 'auto'; } function onLeave(el) { el.style.height = el.scrollHeight + 'px'; el.offsetHeight; el.style.height = '0'; } Це дає нативну анімацію висоти без бібліотек, яка працює при будь-якому вмісті всередині. Економія коду порівняно з jQuery-рішеннями — до 50%.
Як інтегрувати таби з даними Бітрікс?
Вміст вкладок з інфоблоків. Картка товару з вкладками: «Опис» — DETAIL_TEXT з b_iblock_element, «Характеристики» — властивості з b_iblock_element_property, «Відгуки» — дані інфоблоку відгуків. У result_modifier.php формується масив:
$arResult['TABS'] = [ ['id' => 'description', 'title' => 'Опис', 'content' => $arResult['DETAIL_TEXT']], ['id' => 'props', 'title' => 'Характеристики', 'props' => $arResult['DISPLAY_PROPERTIES']], ['id' => 'reviews', 'title' => 'Відгуки', 'lazy' => true, 'endpoint' => '/api/reviews/?id=' . $arResult['ID']], ]; Вкладка «Відгуки» позначена прапорцем lazy: true — вміст підвантажується через AJAX лише при першому відкритті. loading стан компонента — спінер на час запиту.
Акордеон FAQ з інфоблоку. Шаблон компонента bitrix:news.list виводить питання та відповіді. Vue-компонент монтується на контейнер, розбирає існуючий HTML через querySelectorAll (прогресивне покращення) або отримує дані через data-items JSON.
Чому варто обрати Vue замість jQuery для табів?
Порівняння підходів:
| Характеристика | jQuery | Vue.js |
|---|---|---|
| HTML-код | Дублювання блоків для кожного стану | Єдиний шаблон з реактивними даними |
| Продуктивність | Завжди рендериться весь вміст | Рендериться лише активна вкладка (v-if) |
| Підтримка | Важко підтримувати при 5+ вкладках | Легко розширювати: додати вкладку — новий запис у масиві |
| URL-синхронізація | Вимагає додаткових костилів | Вбудована через URLSearchParams |
Vue-рішення скорочує обсяг HTML-коду в 2-3 рази та спрощує підтримку. За нашими тестами, перемикання між 10 вкладками на Vue відбувається на 25% швидше, ніж на jQuery.
Кейс: таби на сторінці тарифів з динамічним перемиканням періоду
В одному з проектів наш клієнт, SaaS-продукт на Бітріксі, зіткнувся з проблемою: сторінка тарифів з табами «Місячна оплата» / «Річна оплата». При перемиканні таба ціни на всіх картках тарифів повинні змінюватися без перезавантаження.
jQuery-рішення вимагало дублювати весь HTML з цінами — один набір для місячних цін, другий для річних, і перемикати видимість. При 6 тарифах — 12 блоків HTML, важко підтримувати.
Vue-рішення: один компонент PricingTabs, дані з window.BX_STATE.pricing:
const period = ref('monthly'); // 'monthly' | 'yearly' const plans = computed(() => rawPlans.value.map(plan => ({ ...plan, price: period.value === 'yearly' ? Math.round(plan.yearlyPrice / 12) : plan.monthlyPrice, badge: period.value === 'yearly' ? `Економія ${plan.yearlySaving}%` : null })) ); Ціни зберігаються в JSON, обчислюються реактивно при зміні періоду. Анімація зміни ціни — <Transition name="price-flip"> з CSS rotateX. Дані в PHP заповнюються з інфоблоку «Тарифи» з полями MONTHLY_PRICE, YEARLY_PRICE. Розробка зайняла 2 дні. Зв'яжіться з нами, щоб обговорити подібний кейс для вашого проекту.
Як забезпечити доступність та SEO для табів?
Таби без ARIA — поширена помилка. Правильна розмітка:
<div role="tablist"> <button role="tab" :aria-selected="activeTab === 'desc'" :aria-controls="'panel-desc'"> Опис </button> </div> <div role="tabpanel" id="panel-desc" :hidden="activeTab !== 'desc'"> <!-- вміст --> </div> Атрибут hidden замість v-show з display: none — screen readers коректно ігнорують приховані панелі. Клавіатурна навігація між вкладками — ArrowLeft/ArrowRight через onKeydown.
SEO-аспект: пошукові системи індексують вміст вкладок, якщо він присутній в HTML. При v-if (лінивий рендер) — перша вкладка рендериться серверно через Bitrix-шаблон, інші завантажуються через AJAX. Для Googlebot це прийнятно — він виконує JavaScript, але із затримкою. Для критичного SEO-контенту (характеристики товару) — завжди рендеримо в HTML, ховаємо через hidden. Детальніше про ARIA читайте в Wikipedia: ARIA та MDN документації.
Типові помилки при розробці табів та акордеонів
- Використання v-show замість v-if для прихованих вкладок — вміст залишається в DOM і уповільнює рендеринг. Обирайте v-if для лінивого завантаження.
- Забули про hidden атрибут: screen reader може читати приховані панелі. Завжди додавайте
:hidden="activeTab !== 'desc'". - Анімація акордеона через CSS height: не працює для auto. Використовуйте JavaScript hooks Vue Transition.
Що входить у розробку та терміни?
- Аналітика: визначення джерел даних, прототипування компонентів
- Проєктування: архітектура Vue-компонентів, контракти з бекендом
- Реалізація: розробка табів/акордеонів на Vue, інтеграція з інфоблоками та API
- Тестування: крос-браузерне, accessibility, продуктивність
- Документація: опис компонентів, приклади використання
- Підтримка: гарантія 3 місяці
| Компонент | Орієнтовний термін |
|---|---|
| Таби зі статичним вмістом + URL-збереження | 1-2 дні |
| Таби з лінивим завантаженням вкладок | 2-3 дні |
| Акордеон з анімацією | 1 день |
| Пов'язані таби + динамічні дані (як приклад з цінами) | 3-5 днів |
Терміни визначаються кількістю джерел даних, вимогами до анімацій та складністю інтеграції з Бітрікс-компонентами. Отримайте консультацію по вашому проекту — ми підберемо оптимальне архітектурне рішення.
Замовте розробку табів під ключ — ми підготуємо комерційну пропозицію за 1 робочий день. Зв'яжіться з нами, щоб обговорити деталі вашого проекту.







