Поскольку веб-приложения становятся все более сложными, нам нужен способ разделить код на управляемые части. Для этого мы можем использовать веб-компоненты для создания многоразовых блоков пользовательского интерфейса, которые мы можем использовать в нескольких местах.
В этой статье мы рассмотрим, как использовать шаблоны и слоты с веб-компонентами.
Шаблоны
Мы можем использовать элемент template
для добавления контента, который не отображается в DOM. Это позволяет нам включить их в любой другой элемент, написав следующий HTML-код:
<template> <p>Foo</p> </template>
Затем мы можем написать следующий код JavaScript, чтобы включить его на страницу:
const template = document.querySelector('template'); const templateContent = template.content; document.body.appendChild(templateContent);
Когда мы загружаем страницу, мы должны видеть «Foo» на странице. Элемент p
должен отображаться, когда мы проверяем код для «Foo». Это подтверждает, что элемент template
не влияет на разметку.
Использование шаблонов с веб-компонентами
Мы также можем использовать их с веб-компонентами. Чтобы использовать его, мы можем получить элемент template
в классе для веб-компонента точно так же, как мы это делаем вне веб-компонента.
Например, мы можем написать:
customElements.define('foo-paragraph', class extends HTMLElement { constructor() { super(); let template = document.querySelector('template'); let templateContent = template.content; const shadowRoot = this.attachShadow({ mode: 'open' }) .appendChild(templateContent.cloneNode(true)); } })
В приведенном выше коде мы получаем элемент template
и вызов cloneNode
для templateContent
, который имеет template.content
в качестве значения для получения содержимого шаблона.
Затем мы вызываем cloneNode
для клонирования дочерних узлов template.content
в дополнение к самому узлу. На это указывает аргумент true
вызова функции cloneNode
.
Наконец, мы прикрепили клонированный templateContent
к теневому корню веб-компонента с помощью методов attachShadow
и appendChild
.
Мы также можем включить стиль в элемент template
, чтобы мы могли повторно использовать его, как мы это делаем с разметкой HTML.
Например, мы можем изменить элемент template
на:
<template> <style> p { color: white; background-color: gray; padding: 5px; } </style> <p>Foo</p> </template>
Тогда мы должны увидеть:
Слоты
Чтобы сделать наши шаблоны более гибкими, мы можем добавить к ним слоты для отображения содержимого по своему желанию вместо статического содержимого. С помощью слотов мы можем передавать контент между открывающими и закрывающими тегами нашего веб-компонента.
У него более ограниченная поддержка, чем у шаблонов. Слоты можно использовать с Chrome 53 или новее, Opera с версии 40, Firefox с версии 59 и не поддерживается в Edge.
Например, мы можем добавить несколько слотов, написав:
<template> <slot name="foo">Default text for foo</slot> <slot name="bar">Default text for bar</slot> <slot name="baz">Default text for baz</slot> </template>
Затем, учитывая, что у нас есть тот же код, что и раньше, для определения элемента foo-paragraph
в JavaScript, мы можем использовать его следующим образом:
<foo-paragraph> <p slot='foo'>foo</p> <p slot='bar'>bar</p> <p slot='baz'>baz</p> </foo-paragraph>
Результатом будет:
foo bar baz
Если мы опустим элементы внутри тегов foo-paragraph
, мы получим текст по умолчанию:
Default text for foo Default text for bar Default text for baz
В приведенном выше коде мы называем слоты атрибутом name
в элементе template
, затем в нашем веб-компоненте мы заполняем слоты, которые мы определили с помощью атрибута slot
.
Мы можем стилизовать их как любой другой элемент template
. Чтобы стилизовать их, мы выбираем элементы, которые будут стилизованы, с помощью селектора для элементов, которые мы заполняем в гнездах.
Например, мы можем написать:
<template> <style> ::slotted(p) { padding: 5px; background-color: black; color: white; } ::slotted(p[slot='foo']) { background-color: gray; } </style> <slot name="foo">Default text for foo</slot> <slot name="bar">Default text for bar</slot> <slot name="baz">Default text for baz</slot> </template> <foo-paragraph> <p slot='foo'>foo</p> <p slot='bar'>bar</p> <p slot='baz'>baz</p> </foo-paragraph>
Псевдоэлемент ::slotted
представляет элементы, которые были помещены в слот внутри шаблона HTML. Следовательно, мы можем использовать его для выбора элементов слота, которые мы хотим стилизовать.
В аргументе ::slotted
мы можем передать элемент, который мы хотим стилизовать, если он был передан в слот. Это означает, что только p
элементов, которые передаются, будут иметь стили, примененные к ним.
::slotted(p[slot=’foo’])
означает, что к элементу p
со значениями атрибутов slot
foo
будет применен стиль.
Тогда после применения стилей у нас должно получиться следующее:
Шаблоны и слоты позволяют нам создавать повторно используемые компоненты, которые мы можем использовать в веб-компонентах. Элемент template
не отображается во время рендеринга, поэтому мы можем разместить их где угодно и использовать их по своему усмотрению в любом веб-компоненте.
Благодаря слотам у нас больше гибкости при создании веб-компонентов, поскольку мы можем создавать компоненты, в которые мы можем вставлять другие элементы, чтобы заполнить слоты.
В любом случае мы можем применять стили к элементам по своему желанию. У нас есть псевдоэлемент ::slotted
для применения стилей к определенным элементам в слотах.