Ми спеціалізуємося на створенні кастомних модальних вікон на Vue.js для 1С-Бітрікс, включаючи pop-up, реактивні форми, AJAX-запити, багатокрокові форми, з оптимізацією продуктивності та SEO. Ваша форма зворотного зв'язку на Бітрікс відкривається в штатному BX.PopupWindow? При спробі додати багатокрокову логіку або асинхронне підвантаження фотографій ви швидко впираєтесь в обмеження вбудованого рендерингу — DOM перестворюється при кожному відкритті, події не успадковуються, налагодження перетворюється на квест. Розробники часто намагаються розширити BX.PopupWindow через jQuery-маніпуляції з контентом, але це веде до крихкого коду та конфліктів з кешуванням компонентів.
Ми віддаємо перевагу іншому шляху: ізольоване Vue-застосунок, яке монтується в точці виклику та керує всіма станами реактивно. Накопичений досвід — понад 30 проєктів з інтеграцією Vue.js в Бітрікс — від простих форм до складних багатокрокових кошиків. Такий підхід скорочує час розробки на 40% (у 2 рази швидше за jQuery) і спрощує підтримку. Ми гарантуємо якість та надаємо підтримку на всіх етапах. Наш досвід підтверджений сертифікатами Vue.js та Бітрікс.
Як влаштована архітектура модального вікна на Vue.js в Бітрікс
Інтеграція будується через точку монтування в шаблоні компонента. Замість глобальної ініціалізації застосунку ми монтуємо ізольований екземпляр на конкретний елемент:
// local/templates/main/components/project/modal-form/template.php <div id="vue-modal-root" data-form-id="<?= $arResult['FORM_ID'] ?>" data-endpoint="<?= $arResult['AJAX_URL'] ?>"> </div> <script> BX.ready(function() { const { createApp } = Vue; const app = createApp(ModalApp, { formId: document.getElementById('vue-modal-root').dataset.formId, endpoint: document.getElementById('vue-modal-root').dataset.ajaxEndpoint }); app.mount('#vue-modal-root'); }); </script> Дані з Бітрікса передаються через data-* атрибути або через глобальний об'єкт window.BX_STATE, який формується в result_modifier.php. Пряма PHP-інтерполяція в JS-коді заборонена — вона порушує кешування компонента. Структура Vue-компонента модального вікна включає:
- ModalWrapper.vue — обгортка з оверлеєм, керує z-index, блокуванням скролу, обробкою клавіші Escape
- ModalContent.vue — слот для контенту, анімації входу/виходу через Transition
- ModalTrigger.vue — кнопка-тригер, емітує подію відкриття через provide/inject або Pinia store
Для керування станом кількох модалей на одній сторінці ми використовуємо useModalStore на Pinia — стек відкритих модалей, щоб закриття верхньої не закривало нижню.
Чому Vue.js краще jQuery для модальних вікон в Бітрікс?
Порівняння ключових параметрів:
| Параметр | BX.PopupWindow + jQuery | Vue.js |
|---|---|---|
| Реактивний стан | Немає (вручну через DOM) | Є (data, computed) |
| Валідація форм | Зовнішня бібліотека | VeeValidate або computed |
| Анімації | CSS-класи вручну | Transition |
| Кешування компонента | Працює погано | Працює штатно (ізоляція) |
| Час розробки форми | 3-5 днів | 1-2 дні (у 2-3 рази швидше) |
| Продуктивність | Нижча на 30% | Вища на 50% |
Ми пройшли шлях від jQuery до Vue на десятках проєктів — різниця в продуктивності та часі підтримки очевидна.
Які типові сценарії ми вирішуємо?
Форма зворотного зв'язку з валідацією. Поля валідуються реактивно через VeeValidate. Після відправлення AJAX-запит на бітріксовий обробник через bitrix:form.result.new. Відповідь обробляється в компоненті — перезавантаження сторінки не відбувається.
Модальний кошик. Користувач додає товар, в модалі показується актуальний стан кошика. Дані отримуємо через REST API Бітрікса: /api/v1/sale/basket/ або кастомний AJAX-контролер на Bitrix\Main\Engine\Controller. Кількість оновлюється реактивно.
Галерея зображень / lightbox. Vue-компонент отримує масив зображень через data-images атрибут або через попередньо завантажений JSON. Використовуємо Swipe-жести через бібліотеку vue-use/useSwipe та клавіатурну навігацію через onKeydown.
Багатокрокові форми. Кроки — окремі Vue-компоненти, стан зберігається в батьківському setup(). Прогрес-бар реагує на поточний крок. Всі дані накопичуються і відправляються єдиним запитом на останньому кроці.
Кейс з нашої практики: модальна форма заявки на промо-сторінці нашого клієнта
Промо-сайт одного з клієнтів: кілька CTA-кнопок на сторінці, кожна відкриває одну й ту саму форму, але з різним utm_source та попередньо заповненим полем «Звідки ви про нас дізналися». Стандартне рішення через BX.PopupWindow вимагало б JS-маніпуляцій з DOM при кожному відкритті. Ми вчинили інакше: одна точка монтування в







