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 🛠️
Для создания кастомного элемента нужно:
- Объявить класс, который расширяет
HTMLElement - Зарегистрировать элемент через
customElements.define()
class UserCard extends HTMLElement {
constructor() {
super();
// Логика инициализации
}
}
// Регистрация элемента с именем тега
customElements.define('user-card', UserCard);
Важно: Имя кастомного элемента должно содержать дефис (user-card, my-button и т.д.) — это требование спецификации.
Жизненный цикл элемента 🔄
Custom Elements имеют встроенные методы жизненного цикла:
connectedCallback()— вызывается при добавлении элемента в DOMdisconnectedCallback()— при удалении из DOMattributeChangedCallback()— при изменении атрибутов
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>
`;
}
}
Работа с атрибутами и свойствами ⚙️
Кастомные элементы могут реагировать на изменения атрибутов. Для этого нужно:
- Определить наблюдаемые атрибуты через статическое свойство
observedAttributes - Реализовать метод
attributeChangedCallback
class UserCard extends HTMLElement {
static get observedAttributes() {
return ['name', 'avatar']; // Список отслеживаемых атрибутов
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`Атрибут ${name} изменился с ${oldValue} на ${newValue}`);
this.render();
}
}
Полезные практики и советы 💡
- Инкапсуляция стилей: Используйте Shadow DOM для изоляции стилей компонента
- Слоты: Добавляйте гибкости через
<slot>элементы - События: Генерируйте кастомные события через
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>