При разработке интернет-магазина на 1С-Битрикс с Vue.js обычно всё начинается с одного компонента — корзины или фильтра. Через месяц появляется второй, третий, и каждый использует свою логику работы с сервером, своё хранилище, свои стили. Состояние корзины в шапке расходится с состоянием в попапе, код AJAX дублируется, а стили ломают вёрстку. Мы видели это десятки раз. Единственное надёжное решение — не набор компонентов, а архитектура: система, где все части используют общее состояние, единый API-слой и дизайн-токены. Наш опыт — 10+ лет в разработке Битрикс-проектов — позволяет строить такие системы быстро и надёжно. При системном подходе время разработки нового компонента сокращается на 40%, а количество ошибок уменьшается в 2 раза. Средняя экономия на поддержке составляет от 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. Системный подход позволяет покрыть тестами как бизнес-логику, так и отрисовку, что даёт уверенность при рефакторинге.
Что входит в работу
| Deliverable | Описание |
|---|---|
| Документация архитектуры | Схема интеграции, диаграмма компонентов, описание 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 в Битрикс — мы покажем, как сэкономить время и деньги. Гарантируем качество и соблюдение сроков.







