Всякий раз, когда мы используем любую из представленных на рынке интерфейсных сред, таких как React, Angular, Vue и т. д., мы в основном разбиваем наш пользовательский интерфейс на более мелкие управляемые части, называемые компонентами. Но задумывались ли вы когда-нибудь о том, можем ли мы разделить наш пользовательский интерфейс на компоненты без использования этих фреймворков?
Ответ на этот вопрос — да, и в этом нам помогают веб-компоненты.

Что такое веб-компоненты?

Веб-компоненты — это набор определенных веб-API, которые позволяют нам разделить наш пользовательский интерфейс на более мелкие блоки, называемые компонентами. Это помогает нам инкапсулировать функциональность компонента в тег HTML, который мы затем можем использовать в любом месте нашего веб-приложения.
Теперь вы можете подумать, что это звучит великолепно, но нам, возможно, придется что-то установить?
Ответ на это «нет», вам не нужно ничего устанавливать для создания собственного веб-компонента, все это предлагает вам ванильный JavaScript.
Еще одна интересная особенность веб-компонентов заключается в том, что впоследствии их можно использовать с другими фреймворками, такими как React, Angular и Vue.

Технологии веб-компонентов

Чтобы предоставить вам функциональность, инкапсулированную в некоторые теги HTML, веб-компоненты используют 3 основные технологии. Эти технологии помогают создавать универсальные компоненты без риска их столкновения в любой точке нашего веб-приложения.
Эти 3 основные технологии:

1. Пользовательские элементы:- Пользовательские элементы позволяют нам создавать собственные собственные HTML-элементы или расширять уже существующие HTML-элементы и изменять их в соответствии с нашими требованиями. Чтобы создать собственный пользовательский элемент, нам нужно создать класс JavaScript, который расширяет класс HTMLElement, чтобы определить функциональные возможности уже существующих тегов HTML. Пользовательские элементы имеют определенные методы жизненного цикла для определения событий, через которые будет проходить наш элемент.
Некоторые из этих методов жизненного цикла:

- constructor(): - ведет себя аналогично тому, как ведет себя конструктор в обычных объектно-ориентированных языках программирования. Метод жизненного цикла конструктора вызывается при создании экземпляра нашего элемента. Наиболее распространенные действия в конструкторе — это инициализация состояния, добавление прослушивателей событий и т. д.
connectedCallback(): — этот метод жизненного цикла вызывается, когда наш элемент вставляется в DOM. (Объектная модель документа).
- disconnectedCallback(): этот метод жизненного цикла вызывается в любое время, когда наш элемент удаляется из DOM.
- attributeChangedCallback():- Этот метод жизненного цикла вызывается, когда любой атрибут добавляется, удаляется, обновляется или заменяется в нашем элементе. Этот метод жизненного цикла принимает 3 параметра attributeName, oldValue и newValue.

2. Shadow DOM:- Shadow DOM позволяет нам инкапсулировать «теневой» DOM для нашего элемента. Это инкапсулирует стили и разметку для наших автономных компонентов. Это дает нашему элементу собственную идентичность, которая отделяет его от общего DOM веб-страницы.
Shadow DOM помогает предотвратить коллизию стилей и функций нашего компонента с общим глобальным стилем и функциями страницы. Теневой DOM создается с помощью метода attachShadow с именем нашего элемента:

element_name.attachShadow({mode:open})

3. Шаблоны HTML:- Шаблоны HTML позволяют нам определять инкапсулированную разметку веб-компонента. Тег шаблона хранит разметку на странице и может включать как HTML, так и CSS для нашего компонента. Слоты используются для добавления пользовательского текста в наш компонент. И шаблон, и слот позволяют нам писать разметку, которая не отображается на отображаемой странице.

Давайте теперь создадим наш собственный веб-компонент…

Создание компонента

Чтобы создать собственный веб-компонент, выполните следующие действия:

1. Создайте файлы HTML и JS. Прежде всего вам необходимо создать файлы HTML и JS, используя соответствующие расширения .html и .js. Наряду с этим вам также нужно будет связать свой файл JavaScript с HTML с помощью тега script.
<script src="[REPLACE_WITH_JS_FILE_LOCATION]"></script>

2.Создайте класс:- Теперь в файле JavaScript вы создаете класс, который будет определять функциональные возможности вашего веб-компонента.
Вот формат создания класса для вашего веб-компонента: -
class MyComponent extends HTMLElement {
constructor() {
super();
//Initialize the state of our component here
}

3. Прикрепите теневой DOM: - В конструкторе теперь вы можете добавить теневой DOM для вашего компонента. Делается это следующим образом:-
class MyComponent extends HTMLElement {
constructor() {
super();

//Attaching Shadow DOM
this.attachShadow({mode:'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));

Что делает последняя строка, так это то, что она берет структуру нашего компонента, определенную в переменной с именем «шаблон», клонирует ее содержимое, а затем добавляет его к дочернему узлу нашего теневого корневого элемента. Но чтобы это работало, нам нужно определить переменную с именем template перед нашим классом.

const template = document.createElement('template');
template.innerHTML = ‘<style> //Add required styling here </style>
<div class=[ADD_CLASS_NAME] id=[ADD_ID_NAME]> //Add required content here </div>';

class MyComponent extends HTMLElement....

4.Создание атрибутов и доступ к ним. Из HTML мы передаем атрибуты так же, как и с обычными тегами HTML, но для доступа к ним в нашем JavaScript мы используем метод getAttribute в конструкторе.
HTML-код:

<my-component my_attribute="some_value">
</my-component>

JS Code:-
class MyComponent extends HTMLElement {


this.attachShadow({mode: ’open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));

this.shadowRoot.querySelector('div').innerText = this.getAttribute('my_attribute');

5.Доступ к функциям:- Чтобы добавить прослушиватели событий или другие функции JavaScript в свой пользовательский компонент, вы можете добавить идентификатор или класс к элементам HTML шаблона, определенным на шаге 3, а затем получить к ним доступ в классе вашего компонента.
Но убедитесь, что любые прослушиватели событий, которые вы добавляете, должны быть определены в методе connectCallback, потому что это гарантирует, что прослушиватели событий срабатывают только тогда, когда компонент подключен к вашей веб-странице DOM.
Чтобы удалить прослушиватели событий из нашего пользовательского компонента, вы можете вызвать метод removeEventListener в методе жизненного цикла disabledCallback, который гарантирует, что после удаления компонента из фактической модели DOM.

6.Инкапсулируйте свой класс компонента в тег HTML:- Чтобы инкапсулировать и экспортировать содержимое, стиль и функциональность наших пользовательских элементов в наш HTML, мы определяем компонент в конце нашего файла JavaScript вне класса.


window.customElements.define('my-component', MyComponent);

Теперь вы можете использовать тег ‹my-component› в любом месте ваших файлов HTML, и он будет отображаться в соответствии с тем, как вы определили его в классе.