Просто зайдите в npm и введите что-нибудь вроде «datepicker». Вы увидите что-то вроде этого:
react-datepicker angular-datepicker vue-datepicker vue-the-very-last-datepicker vue-the-very-last-datepicker-v2 ...
Средство выбора даты для всех фреймворков от Vue до Angular и до React… Это действительно распространенная проблема в мире Javascript.
Разве не было бы замечательно иметь единственное средство выбора даты, которое можно было бы использовать с любой библиотекой или фреймворком?
Веб-компоненты спешат на помощь!
Технология, лежащая в основе веб-компонентов, позволяет вам создавать свой собственный элемент изначально, без использования какой-либо структуры (!), в браузере и использовать его в своем документе так же, как любой другой элемент HTML, как <input>
или <button>
Это большое преимущество, особенно для создания элементов, которые должны использоваться совместно между проектами, в которых используются разные фреймворки, или в проектах, где не требуется сложный фреймворк, но вы все равно хотите иметь некоторую структуру.
4 строительных блока веб-компонентов
Веб-компоненты представляют собой совокупность следующих четырех технологий:
- Тег HTML
<template>
- Custom Elements API
- Shadow Dom
- Модули ES
Давайте объясним четыре строительных блока, создав нашу собственную кнопку веб-компонента.
›› Исходный код и пример можно найти здесь ›› https://playcode.io/347575?tabs=my-button.js,preview,console
1.Шаблоны: содержимое <template>
не отображается браузером, но вы все равно можете ссылаться на него в Javascript. Благодаря этому он отлично подходит для контента, который вы хотите использовать несколько раз в разных местах, и идеально подходит для использования в веб-компонентах.
Давайте создадим простой HTML-документ index.html
со следующим шаблоном для простой кнопки внутри:
<html> <head></head> <body> <template id="myButton"> <style> div { background: red; color: white; padding: 1em; text-align: center; } </style> <div>Click me</div> </template> </body> </html>
Если вы откроете файл в браузере, ничего не должно отображаться должным образом.
2. API пользовательских элементов: API пользовательских элементов позволяет объединить весь код, необходимый для вашего веб-компонента, в один класс и определить имя тега для вашего элемента.
class MyButton extends HTMLElement {
constructor() {
super.constructor();
}
}
customElements.define('my-button', MyButton);
С customElements.define
мы определяем имя нашего элемента и соответствующий класс. Имя должно иметь знак -
, а класс должен быть наследником HTMLElement.
Теперь вместо того, чтобы помещать тег шаблона непосредственно в основной документ, мы добавим его в наш только что созданный файл javascript следующим образом:
const template = document.createElement('template'); template.innerHTML = `
<style> div { background: red; color: white; padding: 1em; text-align: center; } </style> <div>Click me</div>`;
class MyButton extends HTMLElement { constructor() { super.constructor(); } }customElements.define('my-button', MyButton);
Таким образом, у нас может быть все в одном модуле. На следующем этапе мы добавляем содержимое нашего шаблона к нашему элементу. Для этого сначала рассмотрим теневой дом.
3.Shadow Dom Shadow Dom позволяет вам инкапсулировать ваши стили и структуру разметки. Это позволяет отделить код вашего веб-компонента от остальной части документа. Никаких рамок. Просто чистая технология браузера.
Это круто.
Вам нужно добавить явное прикрепление теневого объекта к вашему элементу следующим образом:
const template = document.createElement('template'); template.innerHTML = `
<style> div { background: red; color: white; padding: 1em; text-align: center; } </style> <div>Click me</div>`;
class MyButton extends HTMLElement { constructor() { super.constructor(); this.attachShadow({mode: 'open'}); // <--- attaching shadow dom! } }customElements.define('my-button', MyButton);
Теперь мы добавим содержимое шаблона в наш теневой дом:
const template = document.createElement('template'); template.innerHTML = `
<style> div { background: red; color: white; padding: 1em; text-align: center; } </style> <div>Click me</div>`;
class MyButton extends HTMLElement { constructor() { super.constructor(); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(template.content.cloneNode(true)); } }customElements.define('my-button', MyButton);
Как видите, мы используем template.content.cloneNode(true)
для клонирования содержимого шаблона, которое затем присоединяем к нашему теневому домену.
Разметка и стили доступны только в нашем компоненте.
Давайте поговорим о том, как использовать кнопку веб-компонента в основном документе.
4. Модули ES вы можете импортировать свой веб-компонент, чтобы использовать его в других веб-компонентах, или просто импортировать его в свой основной документ index.html
сверху, используя <script src="my-button.js type="module"></script>
:
<html> <head> <script src="my-button.js" type="module"></script> </head> <body> <my-button onclick="alert('hi')"></mybutton> </body> </html>
Слот
Что, если мы хотим разрешить пользователю добавлять собственный текст к кнопке вместо фиксированного текста «Нажми меня»? Как в следующем примере:
<my-button>You can click me, sir.</my-button>
Вот тут-то и пригодятся слоты:
Элемент HTML
<slot>
- часть технологического пакета Веб-компоненты - это заполнитель внутри веб-компонента, который вы можете заполнить собственной разметкой […]
Https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot
Таким образом, мы можем добавить <slot></slot>
в наш шаблон в том месте, где мы хотим, чтобы пользовательский текст отображался.
В нашем случае мы заменяем текст «Нажми меня» на <slot></slot>
:
const template = document.createElement('template'); template.innerHTML = `
<style> div { background: red; color: white; padding: 1em; text-align: center; } </style> <!-- we've replaced the text with <slot>--> <div><slot></slot></div>`; class MyButton extends HTMLElement { constructor() { super.constructor(); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(template.content.cloneNode(true)); } }
customElements.define('my-button', MyButton);
Теперь мы можем добавить произвольный текст к кнопке:
<html> <head> <script src="my-button.js" type="module"></script> <style>my-button { margin: 1em; }</style> </head> <body> <my-button onclick="alert('hi');">You can click me, sir</my-button> <my-button onclick="alert('hello');">Banana</my-button> <my-button onclick="alert('hey');">Okaaay!</my-button> </body> </html>
Я также добавил еще несколько кнопок и событий щелчка с окнами предупреждений, чтобы протестировать кнопки.
Вы создали свою первую кнопку веб-компонента!
Я горжусь тобой, сынок.
Посмотрите полный исходный код и демонстрацию здесь: https://playcode.io/347575?tabs=my-button.js,preview,console