Представьте, что вы строите дом из готовых блоков. Каждый блок — это стена, окно или дверь. Вы просто берёте нужный блок и ставите на место. А если блок сломался — чините один, не трогая остальные. Примерно так работают веб-компоненты. Только вместо стен — кнопки, формы, виджеты. И всё это на чистом JavaScript, без React или Vue. Звучит круто? Поехали разбираться.
Что такое веб-компоненты и зачем они нужны PHP-разработчику
Веб-компоненты — это набор стандартов браузера, которые позволяют создавать свои собственные HTML-теги. Например, вы можете сделать тег <my-button>, который будет работать как обычная кнопка, но с вашим стилем и логикой. И никаких сторонних библиотек.
Для PHP-разработчика это особенно полезно. Почему? Потому что часто мы пишем бэкенд на PHP, а фронтенд — на коленке, с кучей скопированного JavaScript. Веб-компоненты помогают навести порядок: вы один раз создаёте компонент, а потом используете его в любом HTML-шаблоне, который генерирует PHP. Это как собрать свой собственный конструктор лего из готовых деталей.
Как устроен веб-компонент: три кита
Любой веб-компонент строится на трёх вещах:
- Custom Elements — это самодельные HTML-теги. Вы определяете новый элемент, даёте ему имя и описываете поведение.
- Shadow DOM — это изоляция стилей и разметки. Внутри компонента свои стили, которые не лезут наружу, и внешние стили не лезут внутрь. Как в консервной банке.
- HTML Templates — это шаблоны, которые можно клонировать и вставлять в DOM. Удобно для повторяющихся структур.
Всё вместе это позволяет создавать компоненты, которые работают как встроенные теги браузера. Никаких конфликтов, никакой магии.
Создаём первый компонент: пользовательский элемент
Давайте напишем простой компонент — кастомную кнопку с иконкой. Для начала определим класс, который наследуется от HTMLElement:
class MyButton extends HTMLElement {
constructor() {
super();
this.innerHTML = ``;
}
}
customElements.define('my-button', MyButton);Теперь в HTML можем использовать:
<my-button label='Отправить'></my-button>Но это простейший случай. Без Shadow DOM стили могут переопределяться. Поэтому давайте добавим Shadow DOM.
Изолируем стили с Shadow DOM
Shadow DOM — это как если бы вы поставили компонент в отдельную комнату с непрозрачными стенами. Стили из внешнего мира туда не проникают.
class MyButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `
`;
}
}
customElements.define('my-button', MyButton);Теперь стили кнопки не сломаются, даже если на странице есть глобальные стили для button. Компонент полностью изолирован.
label, color, size. Это делает компонент гибким, как конструктор.Добавляем шаблоны и слоты
Шаблоны (<template>) позволяют хранить разметку, которая не отображается, пока её не активировать. Слоты — это места, куда можно вставлять контент извне. Например, сделаем карточку товара.
<template id='product-card'>
Название товара
0 руб.
class ProductCard extends HTMLElement {
constructor() {
super();
const template = document.getElementById('product-card');
const content = template.content.cloneNode(true);
this.attachShadow({mode: 'open'}).appendChild(content);
}
}
customElements.define('product-card', ProductCard);Использование:
<product-card>
Ноутбук
50 000 руб.
Отличный ноутбук для работы.
</product-card>Слоты позволяют вставлять любой HTML-контент внутрь компонента, сохраняя его структуру.
Жизненный цикл компонента: когда что происходит
У каждого компонента есть свои этапы жизни. Их можно отслеживать с помощью специальных методов:
| Метод | Когда вызывается |
|---|---|
constructor() | При создании элемента |
connectedCallback() | Когда элемент добавлен в DOM |
disconnectedCallback() | Когда элемент удалён из DOM |
attributeChangedCallback() | Когда изменяется атрибут (нужно указать observedAttributes) |
Пример с отслеживанием атрибута:
class MyButton extends HTMLElement {
static get observedAttributes() {
return ['label'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'label') {
this.shadowRoot.querySelector('button').textContent = newValue;
}
}
}Это удобно, когда данные меняются динамически, например, после AJAX-запроса.
Взаимодействие с PHP: передаём данные из бэкенда
В PHP вы можете генерировать HTML с компонентами, передавая данные через атрибуты. Например:
$products = [
['title' => 'Ноутбук', 'price' => 50000],
['title' => 'Мышь', 'price' => 1500]
];
foreach ($products as $product) {
echo " ";
}Но если данных много, лучше передавать их через data-* атрибуты или JSON в скрипте. Например:
<script>
const data = ;
data.forEach(item => {
const card = document.createElement('product-card');
card.setAttribute('label', item.title);
card.setAttribute('price', item.price);
document.body.appendChild(card);
});
</script>Так вы отделяете данные от представления, и компоненты становятся чистыми.
Что в итоге: резюме
Веб-компоненты на нативном JavaScript — это мощный инструмент для создания переиспользуемых элементов интерфейса. Они работают в любом современном браузере, не требуют фреймворков и легко интегрируются с PHP. Вы получаете изоляцию стилей, модульность и чистый код. Начните с малого: замените повторяющиеся куски HTML на кастомные элементы. Со временем соберёте свою библиотеку компонентов, которая сэкономит часы разработки.
А если захотите углубиться — изучите slot, template и жизненные циклы. Это как перейти от велосипеда к автомобилю: быстрее, удобнее, но требует практики.



