BitrixVue 3 - реактивные интерфейсы в 1С-Битрикс
BitrixVue - тонкая обёртка над Vue 3, которая решает специфические для платформы задачи: централизованную версию библиотеки, изоляцию от глобальной области, локализацию и возможность кастомизировать чужие компоненты без правки исходников.
Как это работает
Это Vue 3 с добавками, а не своя библиотека. Поведение Vue не меняется. Добавляются: единая версия для всех модулей, отсутствие Vue в глобальной области, интеграция с локализацией и динамической загрузкой компонентов, механизмы кастомизации. Ограничения тоже есть: нет серверного рендеринга и однофайловых компонентов.
Запуск в двух режимах. В собираемом коде обёртку импортируют и создают приложение обычным способом. На обычной PHP-странице без сборки загружают расширение и обращаются к обёртке через глобальный объект. Монтировать нужно после готовности DOM.
Компоненты бывают классические и мутабельные. Классический - обычный Vue-объект для внутренних задач. Мутабельный нужен, когда решение будут кастомизировать третьи стороны: его можно менять и клонировать, не трогая исходники. Классический объект напрямую мутировать нельзя - только клонировать.
Мутация и клонирование. Мутация меняет компонент до создания экземпляров: на уже отрисованные объекты и на клоны она не действует. Внутри мутации к оригинальным частям обращаются через специальные префиксы - к родительскому шаблону, методам, наблюдателям и данным. Клонирование всегда работает от оригинала.
Объект $Bitrix - мост к платформе. Внутри компонентов доступны локализация,
события уровня приложения, глобальные данные, проброс контекста контроллера и
клиенты REST и Pull.
Три уровня событий. Компонентный - штатные события Vue на один уровень вверх. Уровень приложения - между частями одного приложения. Уровень сайта - общая шина между разными Vue-приложениями и интерфейсами платформы. Глобальный механизм событий из второй версии больше не поддерживается.
Примеры
1. Запуск приложения
import { BitrixVue } from 'ui.vue3';
const application = BitrixVue.createApp({ data() { return { items: [] }; }, template: ` <div class="my-app"> <div v-for="item in items" :key="item.id">{{ item.title }}</div> </div> `,});
application.mount('#application-inner');// без сборки, прямо на странице\Bitrix\Main\UI\Extension::load('ui.vue3');Важная деталь монтирования: Vue заменяет узел целиком. Если смонтировать приложение прямо на корневой элемент, этот элемент исчезнет. Поэтому внутри корневого контейнера создают вложенный элемент и монтируют на него.
2. Мутабельный компонент и его кастомизация
BitrixVue.mutableComponent('mymodule-item-card', { props: ['item'], template: `<div class="card">{{ item.title }}</div>`,});// кастомизация без правки исходника - до создания экземпляровBitrixVue.mutateComponent('mymodule-item-card', { template: `<div class="card card--custom">#PARENT_TEMPLATE#</div>`, methods: { onClick() { this.parentOnClick(); trackAnalytics(); }, },});// клонирование - всегда от оригиналаconst clone = BitrixVue.cloneComponent('mymodule-item-card', 'my-card-clone', { // изменения клона});Именно ради этого механизма компоненты, предназначенные для сторонней доработки, объявляют мутабельными: партнёр меняет поведение, не форкая ваш код.
3. Локализация и события
export const MyComponent = { computed: { phrases() { return this.$Bitrix.Loc.getFilteredPhrases('MYMODULE_CARD_'); }, }, methods: { notify() { this.$Bitrix.eventEmitter.emit('MyModule:Item:selected', { id: this.item.id }); }, }, template: `<button @click="notify">{{ phrases.MYMODULE_CARD_SELECT }}</button>`,};Вынос фраз в вычисляемое свойство - не украшательство: массовые обращения к локализации прямо в шаблоне заметно нагружают перерисовку.
Для связи с другими интерфейсами страницы используют шину уровня сайта из ядра.
Справочник API
| API | Назначение | Особенности |
|---|---|---|
ui.vue3 | расширение BitrixVue | требует модуль интерфейсов актуальной версии |
BitrixVue.createApp() / mount() | запуск приложения | монтировать после готовности DOM |
BitrixVue.mutableComponent() | мутабельный компонент | для решений, которые будут кастомизировать |
BitrixVue.mutateComponent() | изменение компонента | только до создания экземпляров |
BitrixVue.cloneComponent() | клонирование | всегда от оригинала, работает и с классическими |
| префиксы в мутациях | доступ к оригиналу | родительский шаблон, методы, наблюдатели, данные |
$Bitrix.Loc | локализация | есть выборка фраз по префиксу |
$Bitrix.eventEmitter | события приложения | между частями одного приложения |
$Bitrix.Data | глобальные данные приложения | |
$Bitrix.Application | контекст контроллера | |
$Bitrix.RestClient / PullClient | REST и Pull | на внешних ресурсах клиент задают явно |
EventEmitter из ядра | события уровня сайта | связь с другими приложениями и интерфейсами |
Частые ошибки
Мутация не подействовала. Она применяется только до создания экземпляров и не влияет на клоны. Регистрируйте её раньше, а клоны настраивайте отдельно.
Мутация классического компонента не работает. Такие компоненты можно только клонировать.
Клонирование по имени до загрузки оригинала. Результат будет некорректным - сначала загрузите исходный компонент.
Корневой узел исчез после монтирования. Vue заменяет узел целиком - монтируйте на вложенный элемент.
REST и Pull не работают на внешнем ресурсе. Клиент нужно задать явно, иначе внешний виджет не свяжется с порталом.
Локализация тормозит перерисовку. Массовые обращения к фразам прямо в шаблоне дороги - выносите их в вычисляемое свойство.
Используют события из второй версии. Глобальный механизм событий не поддерживается, вместо него три уровня событий.
Частые вопросы
Чем BitrixVue отличается от обычного Vue 3?
Это тот же Vue 3 плюс решения специфических для платформы проблем: единая версия библиотеки для всех модулей (нет конфликтов), отсутствие Vue в глобальной области, встроенная локализация и события, а главное - возможность кастомизировать чужие компоненты мутацией и клонированием без правки исходников. Из ограничений: нет серверного рендеринга и однофайловых компонентов.
Когда объявлять компонент мутабельным?
Когда его будут дорабатывать третьи стороны - партнёры, интеграторы, другие команды. Мутабельный компонент можно изменить и клонировать снаружи, не форкая код. Для внутренних задач достаточно классического Vue-объекта: он проще и его тоже можно клонировать, просто не мутировать.
Как связать Vue-приложение с остальной страницей?
Через уровни событий. Внутри приложения - штатные события Vue и эмиттер уровня приложения из объекта платформы. Между разными Vue-приложениями и обычными интерфейсами - общая шина событий из ядра. Она же связывает ваше приложение с системными интерфейсами, которые Vue не используют.
Почему после монтирования пропал контейнер?
Потому что Vue заменяет узел монтирования целиком - это стандартное поведение библиотеки. Решение простое: внутри вашего контейнера создайте вложенный элемент и монтируйте приложение на него. Тогда внешний контейнер сохранится и его можно переиспользовать.
Связанные темы
- Ядро BX - события уровня сайта
- UI-библиотека - Vue-версии готовых компонентов
- Подключение JS/CSS - расширения и сборка
- Раздел JS и интерфейсы