Web Components: создание собственных тегов через Custom Elements

Что такое Custom Elements и зачем они нужны? 🔍

Web Components — это набор современных технологий, позволяющих создавать переиспользуемые HTML-элементы с изолированной логикой. Custom Elements — их ключевая часть.

Представьте, что вы можете создать свой собственный тег, например <user-card>, который будет отображать аватар, имя и контакты пользователя. И использовать его в любом месте проекта как обычный HTML-элемент!

<!-- Пример использования кастомного элемента -->
<user-card 
  name="Данила Бежин" 
  avatar="https://example.com/avatar.jpg"
  email="danila@example.com">
</user-card>

Как создать свой первый Custom Element 🛠️

Для создания кастомного элемента нужно:

  1. Объявить класс, который расширяет HTMLElement
  2. Зарегистрировать элемент через customElements.define()
class UserCard extends HTMLElement {
  constructor() {
    super();
    // Логика инициализации
  }
}

// Регистрация элемента с именем тега
customElements.define('user-card', UserCard);

Важно: Имя кастомного элемента должно содержать дефис (user-card, my-button и т.д.) — это требование спецификации.


Жизненный цикл элемента 🔄

Custom Elements имеют встроенные методы жизненного цикла:

  • connectedCallback() — вызывается при добавлении элемента в DOM
  • disconnectedCallback() — при удалении из DOM
  • attributeChangedCallback() — при изменении атрибутов
class UserCard extends HTMLElement {
  connectedCallback() {
    console.log('Элемент добавлен на страницу!');
    this.render();
  }

  render() {
    this.innerHTML = `
      <div class="card">
        <h2>${this.getAttribute('name')}</h2>
        <img src="${this.getAttribute('avatar')}">
      </div>
    `;
  }
}

Работа с атрибутами и свойствами ⚙️

Кастомные элементы могут реагировать на изменения атрибутов. Для этого нужно:

  1. Определить наблюдаемые атрибуты через статическое свойство observedAttributes
  2. Реализовать метод attributeChangedCallback
class UserCard extends HTMLElement {
  static get observedAttributes() {
    return ['name', 'avatar']; // Список отслеживаемых атрибутов
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(`Атрибут ${name} изменился с ${oldValue} на ${newValue}`);
    this.render();
  }
}

Полезные практики и советы 💡

  1. Инкапсуляция стилей: Используйте Shadow DOM для изоляции стилей компонента
  2. Слоты: Добавляйте гибкости через <slot> элементы
  3. События: Генерируйте кастомные события через dispatchEvent

Пример со Shadow DOM:

constructor() {
  super();
  this.attachShadow({ mode: 'open' });
  this.shadowRoot.innerHTML = `
    <style>
      .card { 
        border: 1px solid #ccc;
        padding: 16px;
      }
    </style>
    <div class="card">
      <slot name="content">Default content</slot>
    </div>
  `;
}

Где это применяется в реальных проектах? 🌐

Custom Elements активно используют:

  • В дизайн-системах (например, Material Web Components)
  • Для создания виджетов с изолированной логикой
  • В микрофронтенд-архитектурах
  • Для повторного использования сложных UI-компонентов
<!-- Пример из реального мира -->
<github-repo-card repo="DanilaBezhin/web-components-demo"></github-repo-card>
Скрыть рекламу навсегда

📘 VK Видео — обучение без ограничений

Все уроки доступны без VPN, без блокировок и зависаний.

Можно смотреть с телефона, планшета или компьютера — в любое время.

▶️ Смотреть на VK Видео