Vue интеграция

Интеграция Atomico с Vue строится вокруг совместимости веб-компонентов и реактивной модели Vue. В основе лежит спецификация Custom Elements, позволяющая использовать компоненты Atomico в двусторонней связке с шаблонной системой и реактивными данными Vue.

Для корректной работы необходимо, чтобы приложение Vue было настроено на поддержку Custom Elements. В Vue 3 поддержка является встроенной: достаточно объявить теги веб-компонентов как isCustomElement в настройках компилятора.

Пример настройки Vite для Vue 3:

// vite.config.js
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('my-')
        }
      }
    })
  ]
}

Эта конфигурация позволяет Vue воспринимать теги Atomico как нативные элементы без попыток интерпретации в собственные компоненты.

Регистрация и использование

Компоненты Atomico — Custom Elements, поэтому их регистрация осуществляется один раз при загрузке приложения. Atomico экспортирует функцию customElement, которая связывает функциональный компонент с тегом.

import { customElement } from 'atomico'
import { MyCounter } from './my-counter.js'

customElement('my-counter', MyCounter)

После регистрации элемент доступен в шаблонах Vue аналогично HTML-тегам:

<template>
  <my-counter count="3" />
</template>

Vue не вмешивается в управление жизненным циклом веб-компонента; обновление внутренних состояний Atomico происходит автономно.

Привязка данных

Статические и реактивные значения

Custom Elements принимают входные данные через атрибуты и свойства. Vue позволяет передавать реактивные значения с помощью синтаксиса биндинга:

<my-counter :count="value" />

Внутри Atomico свойства, объявленные через props, синхронизируются с атрибутами и обновляются при изменении. Недопустимо ожидать двустороннюю привязку Vue; обратная передача данных выполняется через кастомные события.

Пропсы как свойства

Atomico трактует пропсы как свойства DOM-элемента. Это означает корректную работу с типами:

MyCounter.props = {
  count: Number,
  label: String,
  active: Boolean
}

При биндинге в Vue значения передаются без сериализации, что избавляет от ручного преобразования типов.

События и реактивный обмен

Доставка событий

Custom Elements dispatch событий через CustomEvent. Vue может слушать такие события так же, как события DOM:

<my-counter @change="onChange" />

Atomico использует camelCase имена событий на уровне пропсов, но Custom Elements транслируют их в kebab-case для HTML. При проектировании компонентов рекомендуется придерживаться kebab-case.

Формат полезной нагрузки

Atomico передает данные в поле detail объекта CustomEvent. В обработчиках Vue доступ осуществляется через event.detail:

function onChange(event) {
  state.value = event.detail.count
}

Такой подход обеспечивает мягкую интеграцию с реактивной системой Vue и не требует специальных адаптеров.

Слоты и составление контента

Vue корректно обрабатывает слоты, переданные в веб-компоненты. Atomico реализует стандартный <slot> без дополнительных соглашений. Многоуровневые и именованные слоты поддерживаются браузером нативно.

<my-card>
  <template #header>Заголовок</template>
  Основной текст
  <template #footer>Подвал</template>
</my-card>

Vue преобразует именованные слоты в привычный HTML-вид, который корректно интерпретируется Atomico.

Стилизация

Shadow DOM и изоляция стилей

Atomico по умолчанию использует Shadow DOM. Это обеспечивает изоляцию стилей и предотвращает пересечение с глобальными стилями Vue. Для переопределения стилей применяется CSS Custom Properties:

my-counter {
  --color: #222;
}

Если требуется отказаться от Shadow DOM для более тесной интеграции со стилями Vue, Atomico позволяет отключить его на уровне компонента:

MyCounter.styles = null

Однако такой подход нарушает инкапсуляцию и должен применяться осознанно.

Взаимодействие с системами дизайна

Vue-библиотеки компонентов и дизайн-системы могут сосуществовать с Atomico на уровне глобальных CSS и токенов. Подход с Custom Properties обеспечивает единообразие темизации без зависимости от конкретного фреймворка.

Серверный рендеринг

Vue SSR не рендерит элементы Atomico сам по себе, но корректно выводит Custom Elements в HTML. Ключевые ограничения:

  • отсутствие исполнения lifecycle-логики Atomico на сервере;
  • инициализация компонентов происходит на клиенте;
  • гидрация Vue не конфликтует с Custom Elements.

SSR полезен для SEO и начальной отрисовки, но функциональная логика веб-компонентов выполняется после монтирования.

Производительность и микроинтерактивность

Atomico ориентирован на функциональный подход и эффективные обновления через Hooks. В контексте Vue веб-компоненты Atomico используются как автономные микро-виджеты:

  • высокий уровень инкапсуляции и переиспользования;
  • отсутствие оверхеда от реактивности Vue внутри компонента;
  • минимальная связность кода между фреймворками.

Интеграция оправдана в системах, где Vue занимается декларативной композицией, а Atomico реализует детализированные интерактивные элементы.

Типовые сценарии использования

Встраивание независимых виджетов

Например, счетчики, карточки, графические элементы или контролы форм. Vue взаимодействует с ними через событийную модель и управление пропсами.

Обмен между микрофронтендами

Custom Elements служат универсальным интерфейсом между разными фреймворками. Atomico привлекателен своей компактностью и прозрачной моделью компонентов.

Миграция и совместная эволюция приложений

Использование Atomico позволяет добавлять новые компоненты в существующий Vue-код без переписывания ядра приложения, что снижает стоимость миграции и повышает срок жизни кода.

Ключевые технические особенности интеграции

  • Custom Elements выступают контрактом между Vue и Atomico.
  • Пропсы синхронизируются как DOM-свойства.
  • События передаются через CustomEvent и доступны для реактивной обработки Vue.
  • Слоты совместимы на уровне стандартов браузера.
  • Shadow DOM обеспечивает стильовую изоляцию.
  • SSR работает в режиме статического вывода разметки.

Такой подход сохраняет сильные стороны обоих инструментов и делает интеграцию предсказуемой и технологически чистой.