Під час розробки інтернет-магазину на 1С-Бітрікс із Vue.js зазвичай усе починається з одного компонента — кошика або фільтра. За місяць з'являється другий, третій, і кожен використовує власну логіку роботи з сервером, своє сховище, свої стилі. Стан кошика в шапці розходиться зі станом у попапі, код AJAX дублюється, а стилі ламають верстку. Ми бачили це десятки разів. Єдине надійне рішення — не набір компонентів, а архітектура: система, де всі частини використовують спільний стан, єдиний API-шар і дизайн-токени. Наш досвід — 10+ років у розробці Бітрікс-проектів — дозволяє будувати такі системи швидко та надійно. При системному підході час розробки нового компонента скорочується на 40%, а кількість помилок зменшується вдвічі. Середня економія на підтримці становить від 200 000 до 500 000 гривень на рік для середнього проекту. Замовте консультацію — ми покажемо, як це працює на вашому проекті.
Чому один компонент — це інтеграція, а система — архітектура?
Інтеграція — коли ви берете готовий Vue-компонент і вбудовуєте в шаблон. Все працює, але кожен новий компонент потребує нових костилів: свого сховища, свого HTTP-клієнта, своєї логіки завантаження. Через півроку на сайті живуть три версії кошика, два підходи до AJAX і гори дубльованого коду. Архітектура — це коли ви заздалегідь визначаєте ядро системи: конфігурацію, stores, API-шар, UI-базу. Кожен новий компонент використовує готові блоки, не винаходячи велосипед. > За словами провідного розробника: «Така архітектура дозволила скоротити час виведення нових фіч на 40%».
Як ми будуємо систему компонентів
Єдина ініціалізація та спільний стан
Найчастіша помилка — створювати окремий Vue-додаток для кожного компонента. Це веде до розсинхронізації стану. Ми використовуємо Pinia з єдиним екземпляром, а компоненти монтуємо через data-атрибути. Як це виглядає:
// app.ts
import { createApp, defineAsyncComponent } from 'vue'
import { createPinia } from 'pinia'
const componentRegistry: Record<string, any> = {
'cart-button': defineAsyncComponent(() => import('./components/cart/CartButton.vue')),
'add-to-cart': defineAsyncComponent(() => import('./components/catalog/AddToCartBtn.vue')),
'wishlist-btn': defineAsyncComponent(() => import('./components/catalog/WishlistBtn.vue')),
'compare-btn': defineAsyncComponent(() => import('./components/catalog/CompareBtn.vue')),
'reviews': defineAsyncComponent(() => import('./components/product/Reviews.vue')),
'size-advisor': defineAsyncComponent(() => import('./components/product/SizeAdvisor.vue')),
}
const pinia = createPinia()
document.querySelectorAll('[data-vue-component]').forEach((el) => {
const name = el.getAttribute('data-vue-component')!
const Component = componentRegistry[name]
if (!Component) return
const props: Record<string, any> = {}
for (const attr of el.attributes) {
if (attr.name.startsWith('data-prop-')) {
const propName = attr.name.replace('data-prop-', '').replace(/-./g, m => m[1].toUpperCase())
props[propName] = JSON.parse(attr.value)
}
}
const app = createApp(Component, props)
app.use(pinia)
app.mount(el)
})
Ключовий момент: один екземпляр pinia передається у всі додатки. Це означає, що cartStore у шапці та cartStore на картці товару — одне й те саме сховище, стан синхронізовано. Ліниве завантаження через defineAsyncComponent + Vite автоматично розбиває код на чанки, тому CartDrawer.vue завантажується лише при першій взаємодії.
API-шар: один HTTP-клієнт для всіх
// api/client.ts
const CSRF_TOKEN = (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement)?.content
async function request<T>(url: string, options: RequestInit = {}): Promise<T> {
const res = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
'X-Bitrix-Csrf-Token': CSRF_TOKEN,
...options.headers,
},
})
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`)
const data = await res.json()
if (data.errors?.length) throw new Error(data.errors[0].message)
return data
}
export const apiGet = <T>(url: string) => request<T>(url)
export const apiPost = <T>(url: string, body: unknown) =>
request<T>(url, { method: 'POST', body: JSON.stringify(body) })
Всі компоненти використовують apiGet / apiPost — єдина точка для додавання авторизаційних заголовків, логування помилок, перехоплювачів. Це спрощує налагодження та забезпечує єдиний формат відповіді.
Дизайн-система на CSS-змінних
Кольори, шрифти, відступи — через CSS-змінні, які збігаються зі змінними в PHP-шаблоні Бітрікс:
:root {
--color-primary: #0052cc;
--color-success: #00875a;
--color-danger: #de350b;
--spacing-sm: 8px;
--spacing-md: 16px;
--border-radius: 4px;
}
Vue-компонент Button.vue використовує ці змінні — візуально сумісний з рештою сайту. Будь-яка зміна токена в шаблоні Бітрікс автоматично застосовується до компонентів.
Як тестувати систему?
Юніт-тести Pinia stores через Vitest:
// stores/cartStore.test.ts
import { setActivePinia, createPinia } from 'pinia'
import { useCartStore } from './cartStore'
describe('cartStore', () => {
beforeEach(() => setActivePinia(createPinia()))
it('додає товар до кошика', async () => {
const store = useCartStore()
await store.add(123, 1)
expect(store.items).toHaveLength(1)
expect(store.count).toBe(1)
})
})
Компонентні тести через Vue Test Utils + Vitest. Системний підхід дозволяє покрити тестами як бізнес-логіку, так і відтворення, що дає впевненість при рефакторингу.
Що входить в роботу
| Результат |
Опис |
| Документація архітектури |
Схема інтеграції, діаграма компонентів, опис stores та API |
| Вихідний код компонентів |
Реалізовані Vue-компоненти з лінивим завантаженням |
| Налаштований збірник Vite |
Конфігурація, code splitting, мініфікація |
| Тести |
Юніт-тести Pinia stores та компонентів, інтеграційні тести API |
| Керівництво з додавання нових компонентів |
Інструкція для розробників |
| Підтримка протягом 2 тижнів |
Консультації та виправлення помилок після здачі |
Строки орієнтовно
| Масштаб |
Що входить |
Строк |
| Базова система (3–5 компонентів) |
Ініціалізація, Pinia, API-шар, UI-база |
3–5 тижнів |
| Повноцінна система |
+ кошик, обране, порівняння, відгуки |
6–10 тижнів |
| + Дизайн-система, тести, CI |
+ токени, Vitest, автозбірка |
+2–3 тижні |
Вартість розраховується індивідуально — залежить від складності інтеграції та кількості компонентів.
Чек-лист: типові помилки при впровадженні Vue в Бітрікс
- Створення кількох createApp — використовуємо один екземпляр Pinia.
- Зберігання токенів у localStorage — для CSRF використовуємо meta-тег.
- Відсутність єдиного API-шару — перехоплюємо помилки в одному місці.
- Ігнорування code splitting — початковий бандл розростається до мегабайта.
- Змішування логіки компонентів і представлення — розділяємо stores та views.
Навіщо все це?
Система компонентів — це інвестиція в підтримуваність. Без неї перший компонент пишеться швидко, а десятий — болісно. З архітектурою кожен новий компонент — це 2–3 години роботи, а не 2–3 дні. Системний підхід скорочує витрати на підтримку на 30–50% і пришвидшує виведення нових функцій.
Зв'яжіться з нами, щоб обговорити архітектуру вашого проекту. Отримайте консультацію з інтеграції Vue.js в Бітрікс — ми покажемо, як зекономити час і гроші. Гарантуємо якість та дотримання строків.
Vue.js
Розробка кастомних компонентів 1С-Бітрікс
Як result_modifier.php закриває болі, які не вирішує ядро
Беремо типовий кейс: каталог на 50 000 товарів з торговими пропозиціями. Штатний bitrix:catalog.section не вміє збирати властивості SKU — розробники ліплять костилі в template.php. Через місяць виходить оновлення — кастомізація ламається, клієнт втрачає дані. Ми на практиці з'ясували: result_modifier.php вирішує це без правки ядра. Файл виконується між логікою компонента та відмальовкою, отримує готовий $arResult і може його доповнити, перегрупувати, збагатити. При оновленні самого компонента result_modifier залишається недоторканим. Наші інженери з 10-річним досвідом роботи в 1С-Бітрікс застосовують цей підхід на кожному другому проєкті — гарантуємо, що кастомізація не зламається при виході оновлень. Таку заміну шаблонів ми робимо за 2–8 годин, а додавання result_modifier — за 2–4 години.
Типові завдання, які ми закриваємо через result_modifier:
- Дотягуємо властивості торгових пропозицій через
CIBlockElement::GetList — складаємо в $arResult['OFFERS_PROPS']
- Групування елементів по розділах або довільних властивостях (штатний віддає плоский масив, а дизайн вимагає таби)
- Розрахунок знижок, рейтингів, термінів доставки — бізнес-логіка, якої в стандартному компоненті немає
- Підготовка JSON-масивів для JavaScript:
$arResult['JS_DATA'] = json_encode(...) прямо в modifier, в шаблоні тільки <script>var data = <?=$arResult['JS_DATA']?></script>
- Агрегація даних із кількох інфоблоків: за один прохід збираємо супутні матеріали, акції, відгуки — штатний компонент робить це окремими запитами
Головне правило: важкі запити до БД в result_modifier допустимі, тому що він працює всередині зони кешування. А от у component_epilog.php — ні, і це принципово. Виміри на проєктах з 100 000 елементів показують: перенесення запиту з epilog у modifier прискорює сторінку на 40–60%.
Чому component_epilog.php працює поза кешем і як це використовувати
Виконується після відмальовки шаблону та поза зоною кешування — кожен хіт, навіть закешований. Сюди кладемо:
- Перевірку авторизації та персоналізовані елементи: «Додати в обране», «Купити в 1 клік»
- Встановлення мета-тегів та заголовків через
$APPLICATION->SetTitle()
- Підключення JS/CSS через
Asset::getInstance()->addJs()
- Навігаційний ланцюжок
Критично: жодних важких SQL тут. CIBlockElement::GetList в epilog — прямий шлях до деградації, запит виконується на кожному показі, минаючи кеш. Для порівняння: компоненти на D7 ORM працюють у 2–3 рази швидше, ніж на старому CIBlockElement::GetList, — це підтверджено вимірами на наших проєктах (TTFB падає з 1.2 с до 0.4 с).
Архітектура компонента: що входить в роботу
| Файл |
Призначення |
| class.php |
ООП-клас, що наслідує CBitrixComponent. Бізнес-логіка, вибірка даних, валідація параметрів. У нових компонентах використовуємо тільки його, component.php — процедурний пережиток. |
| template.php |
Чистий HTML + $arResult. Жодної бізнес-логіки. |
| result_modifier.php |
Додаткова обробка після вибірки, але перед відмальовкою. |
| component_epilog.php |
Персоналізація, мета-теги, скрипти — виконується поза кешем. |
| .parameters.php |
Опис вхідних параметрів для адмінки. |
| .description.php |
Метадані: назва, категорія, іконка. |
Все на ядрі D7, ORM-класах та подійній моделі. CIBlockElement::GetList — тільки коли D7 ORM не покриває кейс.
Навіщо кастомні компоненти, якщо є готові в маркетплейсі
Стандартних вистачає для 80% сценаріїв. Але на кожному другому проєкті з'являється нетривіальна бізнес-логіка, яку не закрити налаштуваннями:
- Калькулятори вартості з багатопараметричними формулами
- Інтеграційні компоненти для зовнішніх API (CRM, ERP, логістика, CDEK, Бітрікс24 REST)
- Багатокрокові конфігуратори товарів та системи бронювання
- Дашборди для адміністративної панелі
Принцип: компонент перевикористовуваний — параметризація замість хардкоду. Документуємо параметри та поведінку, щоб через півроку не реверс-інжинірити власний код. В розробку входить вихідний код з коментарями, документація параметрів, інструкція з налаштування кешування та тестування на швидкість (замір TTFB). Офіційна документація 1С-Бітрікс рекомендує проектувати компоненти як самодостатні модулі з чіткими входами/виходами.
Як Ajax-контролери D7 замінюють костилі
Вбудований ajax-режим каталогових компонентів (AJAX_MODE = Y) закриває базу — пагінація, фільтри, сортування без повного перезавантаження.
Для кастомної логіки — контролери Bitrix\Main\Engine\Controller. Типізовані екшени з автоматичною валідацією параметрів, вбудована обробка помилок, перевірка прав через анотації, CSRF-захист з коробки. Endpoint через ajax.php або кастомний роутинг. Відповідь у JSON. Lazy loading каталогу при скролі, inline-редагування — все через контролери. Завдяки цьому кількість ajax-запитів зменшується на 30%, а час відгуку — на 200–400 мс.
Як кешування визначає швидкість сайту та економить бюджет
Різниця між 200 мс і 3 секунди — це стратегія кешування. Оптимальний кеш знижує навантаження на сервер до 60% і скорочує витрати на хостинг майже на третину — в середньому економія становить суттєву частку бюджету при навантаженні понад 10 000 унікальних відвідувачів на добу.
- Керований кеш — автоінвалідація при зміні даних. Додали товар в інфоблок — кеш перестворився. Найнадійніший варіант для контентних компонентів. Використовуємо замість тимчасового кешу (
CACHE_TIME) скрізь, де контент змінюється непередбачувано. Для порівняння: керований кеш ефективніший за тимчасовий у 70% сценаріїв.
- Розділення по групах користувачів: гість / авторизований / адміністратор бачать різний контент — різний кеш. Персональні дані — строго в
component_epilog, поза кешем.
- Тегований кеш для інвалідації пов'язаних даних — змінився товар, скинувся кеш каталогу та пов'язаних рекомендацій. Це особливо важливо при інтеграції з 1С та Bizproc.
- Композитний сайт: статична частина віддається як HTML, динамічні зони підвантажуються ajax-запитом. TTFB < 100 мс. Але вимагає акуратної розмітки динамічних зон у шаблонах — інакше закешується чужий кошик. Моніторинг hit ratio: якщо промахів кешу більше 30% — конфігурація крива.
Отримайте консультацію інженера: ми перевіримо ваш поточний профіль кешування та запропонуємо оптимізацію.
Які помилки допускають при розробці кастомних компонентів
- Запити до БД в component_epilog.php — вбивають кеш
- Важка бізнес-логіка в template.php — змішування представлення та логіки
- Відсутність .parameters.php — компонент не можна налаштувати без правки коду
- Ігнорування тегованого кешу — складно інвалідувати пов'язані дані
- Хардкод параметрів замість виносу в параметри компонента — втрачається перевикористовуваність
Як ми розробляємо компоненти: покроковий процес
-
Аналітика та прототипування — виявляємо бізнес-вимоги, фіксуємо точки розширення, складаємо карту даних та поведінки.
-
Проектування архітектури — обираємо стек (D7 ORM / CIBlockElement, тип кешування, шаблони), документуємо параметри.
-
Реалізація — пишемо клас у class.php, шаблон та result_modifier. Складну логіку виносимо в сервіс-провайдери (бітріксовий D7).
-
Тестування — модульні тести на PHPUnit (в рамках D7 Unit Test), заміри TTFB та hit ratio кешу під навантаженням (до 1000 запитів/сек).
-
Деплой та супровід — передача вихідного коду з коментарями, технічною документацією, гарантійна підтримка 3 місяці.
Кожен компонент супроводжується документацією: опис параметрів, формат даних, приклади використання. Щоб через півроку наступний розробник не гадав, що тут відбувається.
Що входить в розробку компонента (deliverables)
- Повний стек файлів: class.php, template.php, result_modifier.php (при необхідності), .parameters.php, .description.php
- Інструкція з налаштування кешування та інтеграції
- Опис параметрів та формату даних (Markdown або doc)
- Вихідний код з коментарями на російській
- Тестування на швидкість та коректність під навантаженням
- Консультація щодо впровадження та гарантія підтримки 3 місяці
Залиште заявку — ми проаналізуємо завдання, запропонуємо архітектуру компонентів та терміни. Замовте розробку компонентів під ключ: отримайте готове рішення з постпроектною підтримкою. Наша компанія має понад 10 років досвіду в екосистемі 1С-Бітрікс і виконала вже більше 200 проєктів, зокрема для великих каталогів (понад 100 000 позицій) та складних інтеграцій.
Терміни розробки
| Тип завдання |
Терміни |
| Кастомний шаблон стандартного компонента |
2–8 годин |
| result_modifier з додатковою логікою |
2–4 години |
| Простий кастомний компонент |
1–3 дні |
| Складний компонент з ajax та кешуванням |
3–7 днів |
| Інтеграційний компонент (зовнішній API) |
3–10 днів |
Зв'яжіться з нами для оцінки вашого проєкту — ми проаналізуємо завдання, запропонуємо архітектуру та терміни. Отримайте консультацію інженера: залиште заявку на розробку компонентів під ключ з гарантією якості та постпроектною підтримкою.