Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке веб-компоненти і Shadow DOM і коли вони кращі за компоненти фреймворку?

Веб-компоненти - вбудований у браузер спосіб створювати власні HTML-елементи. Три частини:

1. Користувацькі елементи (custom elements) - власний тег з поведінкою:

class CopyButton extends HTMLElement {
  connectedCallback() {
    this.addEventListener('click', () => {
      navigator.clipboard.writeText(this.getAttribute('text'));
    });
  }
}
customElements.define('copy-button', CopyButton);
<copy-button text="composer require laravel/sanctum">Копіювати</copy-button>

Назва обов'язково містить дефіс - щоб не зіткнутися з майбутніми стандартними тегами. Колбеки життєвого циклу: connectedCallback, disconnectedCallback, attributeChangedCallback (для атрибутів зі списку observedAttributes).

2. Shadow DOM - ізольоване піддерево всередині елемента:

const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
  <style>button { color: red; }</style>
  <button><slot></slot></button>
`;
  • стилі сторінки не проникають усередину, а стилі компонента не витікають назовні - справжня ізоляція CSS;
  • document.querySelector не знаходить елементи всередині тіньового дерева;
  • налаштування ззовні - через CSS-змінні (вони успадковуються крізь межу) і ::part().

3. <template> і <slot> - розмітка-заготовка й місця, куди потрапляє вміст, переданий компоненту.

Коли веб-компоненти доречні:

  • елементи, що мають працювати будь-де: у Blade, Vue, React, на статичній сторінці. Дизайн-системи великих компаній і віджети для вбудовування на чужі сайти;
  • ізоляція стилів від CSS сторінки, яку ви не контролюєте;
  • «острівці» інтерактивності на серверно-рендерених сторінках без фреймворку;
  • довговічність: стандарт браузера не застаріває так, як версії фреймворків.

Обмеження:

  • немає реактивності й шаблонізації з коробки: оновлення DOM при зміні даних - вручну (або бібліотека на кшталт Lit);
  • серверний рендеринг Shadow DOM можливий через декларативний <template shadowrootmode="open">, але екосистема тут слабша, ніж у фреймворків;
  • форми: елементи всередині Shadow DOM не беруть участі у відправці форми без ElementInternals;
  • доступність: зв'язки aria-labelledby і for не працюють крізь межу тіньового дерева;
  • Tailwind не стилізує вміст Shadow DOM - глобальні класи туди не потрапляють.

З фреймворками: Vue вміє компілювати компоненти у веб-компоненти (defineCustomElement), React 19 повноцінно підтримує їх як елементи. Alpine і Livewire працюють з користувацькими елементами як із звичайними тегами (без Shadow DOM).

Докладніше в документації: Веб-компоненти

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання