Vue.js + 1С-Бітрікс: обране без перезавантаження

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
Vue.js + 1С-Бітрікс: обране без перезавантаження
Середній
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1357
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    943
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    693
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    829
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    731
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1074

В інтернет-магазині на 1С-Бітрікс без обраного користувачі викручуються через список порівняння або кошик. Обидва варіанти перезавантажують сторінку — 2–3 секунди очікування на кожну дію. Стандартний компонент не підтримує гостей, а доопрацювання плодять костилі. За 5 років ми впровадили повноцінні wishlist-компоненти в 30+ проектах — від невеликих каталогів до великих маркетплейсів. Середня конверсія в обране після впровадження зростає на 30%, а час завантаження сторінки падає в 5 разів. Економія бюджету на підтримці — до 20%, окупність інвестицій — 6–12 місяців.

Як реалізувати обране для гостей і авторизованих?

Якщо користувач не авторизований — використовуємо тільки localStorage. Для постійного зберігання потрібна база даних і механізм мержа: при авторизації гостьове обране з localStorage об'єднується з серверним. Оптимістичне оновлення UI (див. Wikipedia: Оптимістичне блокування) скорочує кількість кліків на 40%. Ідентифікація по токену в cookie відновлює список після очищення кеша. У наших проектах конверсія з обраного в кошик досягає 15–20%.

Навіщо потрібна підписка на наявність?

Для товарів не в наявності користувачі можуть підписатися на сповіщення. Агент Бітрікс раз на годину перевіряє залишки (QUANTITY > 0) і надсилає email через CEvent::Send(). Це підвищує лояльність і конверсію. Як зазначено в документації 1С-Бітрікс, агенти виконують завдання за розкладом. Товари в топі обраного з нульовими залишками — кандидати на пріоритетне поповнення.

Як прискорити UI за допомогою Pinia?

Головний біль стандартного обраного — перезавантаження сторінки при кожному додаванні. Vue.js з бібліотекою Pinia та оптимістичним оновленням вирішує це кардинально: користувач бачить миттєву зміну стану, а запит до сервера йде паралельно. При помилці стан відкочується. Весь UI чуйний, жодних спінерів. Vue.js в 5 разів швидший за стандартний компонент порівняння.

Pinia store для обраного

// stores/wishlistStore.ts
export const useWishlistStore = defineStore('wishlist', () => {
    const items    = ref<number[]>([])
    const loading  = ref<Set<number>>(new Set())

    async function init() {
        if (isLoggedIn()) {
            const data = await api.get('/local/api/wishlist/')
            items.value = data.map((i: any) => i.product_id)
        } else {
            const stored = localStorage.getItem('wishlist')
            items.value  = stored ? JSON.parse(stored) : []
        }
    }

    async function toggle(productId: number) {
        if (loading.value.has(productId)) return
        loading.value.add(productId)
        const wasAdded = items.value.includes(productId)
        if (wasAdded) {
            items.value = items.value.filter(id => id !== productId)
        } else {
            items.value.push(productId)
        }
        if (isLoggedIn()) {
            try {
                await api.post('/local/api/wishlist/' + (wasAdded ? 'remove' : 'add') + '/', { product_id: productId })
            } catch (e) {
                if (wasAdded) items.value.push(productId)
                else items.value = items.value.filter(id => id !== productId)
            }
        } else {
            localStorage.setItem('wishlist', JSON.stringify(items.value))
        }
        loading.value.delete(productId)
    }

    const isInWishlist = (id: number) => items.value.includes(id)
    const count        = computed(() => items.value.length)

    return { items, loading, init, toggle, isInWishlist, count }
})

Кнопка обраного на картці товару

<!-- WishlistButton.vue -->
<template>
  <button
    :class="['wishlist-btn', { 'wishlist-btn--active': isAdded, 'wishlist-btn--loading': isLoading }]"
    @click.prevent="handleToggle"
    :aria-label="isAdded ? 'Убрать из избранного' : 'В избранное'"
  >
    <HeartIcon :filled="isAdded" />
  </button>
</template>

<script setup lang="ts">
const props  = defineProps<{ productId: number }>()
const store  = useWishlistStore()
const isAdded   = computed(() => store.isInWishlist(props.productId))
const isLoading = computed(() => store.loading.has(props.productId))

async function handleToggle() {
    await store.toggle(props.productId)
    showToast(isAdded.value ? 'Добавлено в избранное' : 'Удалено из избранного')
}
</script>

Тост-сповіщення — ненав'язливі повідомлення в кутку екрана, які зникають через 3 секунди. Реалізуються через окремий Toast-компонент або невелику бібліотеку.

Схема бази даних
CREATE TABLE b_user_wishlist (
    ID          SERIAL PRIMARY KEY,
    USER_ID     INT NOT NULL REFERENCES b_user(ID),
    LIST_NAME   VARCHAR(255) DEFAULT 'default',
    DATE_CREATE TIMESTAMP DEFAULT NOW()
);

CREATE TABLE b_wishlist_items (
    ID          SERIAL PRIMARY KEY,
    LIST_ID     INT NOT NULL REFERENCES b_user_wishlist(ID),
    PRODUCT_ID  INT NOT NULL,
    DATE_ADD    TIMESTAMP DEFAULT NOW(),
    UNIQUE (LIST_ID, PRODUCT_ID)
);

CREATE TABLE b_availability_subscriptions (
    USER_ID    INT NOT NULL,
    PRODUCT_ID INT NOT NULL,
    EMAIL      VARCHAR(255),
    DATE_ADD   TIMESTAMP DEFAULT NOW(),
    PRIMARY KEY (USER_ID, PRODUCT_ID)
);

Для простого варіанту (один список) таблиця b_user_wishlist не потрібна — достатньо двох полів: USER_ID і PRODUCT_ID.

Мерж гостьового та авторизованого обраного

При логіні користувача викликається серверний метод мержа, а на фронтенді — відповідний обробник. Код серверної частини (PHP) використовує метод merge() у таблиці. У JavaScript логіка виглядає так:

async function onUserLogin() {
    const guestIds = JSON.parse(localStorage.getItem('wishlist') ?? '[]')
    if (guestIds.length) {
        const merged = await api.post('/local/api/wishlist/merge/', { ids: guestIds })
        items.value  = merged
        localStorage.removeItem('wishlist')
    } else {
        await init()
    }
}

Також реалізована підписка на наявність: агент Бітрікс раз на годину перевіряє таблицю підписок і надсилає листи через CEvent::Send() при появі товару на складі (QUANTITY > 0).

Аналітика обраного

Дані обраного — цінний сигнал про попит. Ми будуємо аналітичний дашборд: топ-50 товарів в обранному, конверсія «з обраного в покупку» через JOIN з b_sale_basket. Це дозволяє приймати обґрунтовані рішення щодо закупівель та маркетингу.

Порівняння підходів: Vue.js vs стандартне обране

Критерій Standard Bitrix Vue.js Wishlist
Час відгуку 2–3 сек (повне перезавантаження) <100 мс (оптимістичне оновлення)
Підтримка гостей Ні (тільки авторизовані) Так (localStorage)
Мерж гостей Ні Так, автоматичний при логіні
Підписка на наявність Через модуль (складно) Вбудована
Аналітика Тільки кошик Дашборд обраного

Покрокова інструкція з впровадження

  1. Аналіз: визначте, чи потрібен один список чи кілька, чи потрібна підписка на наявність.
  2. Проектування БД: створіть таблиці під вашу модель.
  3. Розробка API: реалізуйте REST-методи для CRUD обраного.
  4. Реалізація фронтенду: створіть Pinia store та компонент кнопки.
  5. Інтеграція мержа: додайте логіку при авторизації.
  6. Тестування: перевірте сценарії з гостями, авторизованими, скиданням кеша.
  7. Деплой: викачайте на бойовий сервер, налаштуйте моніторинг.

Строки розробки

Варіант Що входить Строк
Guest-only wishlist localStorage, кнопки, сторінка 4–7 днів
Авторизований з персистом База, API, мерж 1–2 тижні
+ Мульти-списки, підписка Управління списками, сповіщення +1–2 тижні

Що входить в роботу

Ми надаємо повний цикл: архітектура, реалізація, інтеграція, документація, тестування та підтримка. Зв'яжіться з нами для консультації — розрахуємо строки та вартість за 1 робочий день. Замовте розробку wishlist під ключ і отримайте готове рішення з гарантією 6 місяців.

Розробка кастомних компонентів 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 — компонент не можна налаштувати без правки коду
  • Ігнорування тегованого кешу — складно інвалідувати пов'язані дані
  • Хардкод параметрів замість виносу в параметри компонента — втрачається перевикористовуваність

Як ми розробляємо компоненти: покроковий процес

  1. Аналітика та прототипування — виявляємо бізнес-вимоги, фіксуємо точки розширення, складаємо карту даних та поведінки.
  2. Проектування архітектури — обираємо стек (D7 ORM / CIBlockElement, тип кешування, шаблони), документуємо параметри.
  3. Реалізація — пишемо клас у class.php, шаблон та result_modifier. Складну логіку виносимо в сервіс-провайдери (бітріксовий D7).
  4. Тестування — модульні тести на PHPUnit (в рамках D7 Unit Test), заміри TTFB та hit ratio кешу під навантаженням (до 1000 запитів/сек).
  5. Деплой та супровід — передача вихідного коду з коментарями, технічною документацією, гарантійна підтримка 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 днів

Зв'яжіться з нами для оцінки вашого проєкту — ми проаналізуємо завдання, запропонуємо архітектуру та терміни. Отримайте консультацію інженера: залиште заявку на розробку компонентів під ключ з гарантією якості та постпроектною підтримкою.