В основе Lit лежит декларативное описание DOM через шаблоны. Шаблон в
Lit — это не строка и не фрагмент HTML-документа, а специальная
структура данных, создаваемая при помощи теговой функции
html. Такой подход позволяет фреймворку эффективно
отслеживать изменения, минимизировать операции с DOM и обеспечивать
высокую производительность.
Шаблон представляет собой неизменяемую часть (статическую разметку) и набор динамических выражений. Lit один раз анализирует структуру шаблона и в дальнейшем обновляет только те места, где изменились значения выражений.
import { html } from 'lit';
const template = html`
<p>Текущее значение: ${value}</p>
`;
Выражение внутри ${} может содержать любое
JavaScript-значение: примитив, объект, массив, функцию или другой
шаблон.
htmlhtml — это теговая функция, которая получает массив
строк и массив значений, а на выходе возвращает объект типа
TemplateResult. Этот объект не является DOM-узлом и не
вставляется напрямую в документ. Он используется Lit-движком для
создания и обновления реального DOM.
Ключевые свойства шаблонов Lit:
В отличие от строковой конкатенации HTML, шаблоны Lit защищены от XSS по умолчанию, так как значения автоматически экранируются.
Шаблон сам по себе ничего не отображает. Он передаётся в механизм
рендеринга, который связывает его с DOM. В контексте веб-компонентов Lit
это происходит внутри метода render().
render() {
return html`
<h1>${this.title}</h1>
`;
}
Каждый вызов render() возвращает новый
TemplateResult, но Lit сравнивает его со старым и выполняет
минимальное количество изменений в DOM.
Выражения могут использоваться практически в любом месте HTML-разметки:
html`<span>${message}</span>`
html`<input value=${this.value}>`
Если значение равно null или undefined,
атрибут будет удалён.
Для булевых атрибутов используется префикс ?.
html`<button ?disabled=${this.loading}>`
Атрибут будет присутствовать только при true.
Для установки свойств используется префикс ..
html`<input .value=${this.value}>`
Это важно для работы с объектами, массивами и нестандартными типами данных.
Lit использует нативную модель событий браузера. Обработчики
указываются через префикс @.
html`
<button @click=${this.handleClick}>
Нажать
</button>
`
Функция-обработчик передаётся по ссылке, без вызова. Контекст
this автоматически привязывается к экземпляру
компонента.
Шаблоны можно вкладывать друг в друга без дополнительных обёрток.
const itemTemplate = (item) => html`
<li>${item}</li>
`;
html`
<ul>
${items.map(itemTemplate)}
</ul>
`
Lit корректно обрабатывает массивы шаблонов, создавая и обновляя список элементов.
Для условного отображения используются обычные тернарные операторы или логические выражения.
html`
${this.visible
? html`<p>Отображается</p>`
: html`<p>Скрыто</p>`
}
`
Если результат выражения равен null,
undefined или false, соответствующая часть DOM
не будет создана.
<template>HTML-элемент <template> — это стандартный механизм
браузера для хранения фрагментов разметки, которые не отображаются
сразу. Его содержимое не участвует в рендеринге и не влияет на DOM, пока
не будет явно использовано.
<template id="card-template">
<div class="card">
<h2></h2>
<p></p>
</div>
</template>
Содержимое <template> доступно через свойство
content, представляющее DocumentFragment.
<template> от шаблонов LitНесмотря на схожее название, <template> и шаблоны
Lit решают разные задачи:
<template> — это низкоуровневый API
браузераhtml в Lit — декларативное описание UI с
реактивностьюОсновные различия:
| Критерий | <template> |
Lit html |
|---|---|---|
| Реактивность | отсутствует | встроена |
| Обновление DOM | вручную | автоматически |
| Синтаксис | чистый HTML | HTML + JS |
| Производительность | зависит от реализации | оптимизирована |
<template> внутри LitЭлемент <template> может применяться в Lit, но
чаще всего для интеграции со сторонними библиотеками или при работе с
сырым DOM.
firstUpdated() {
const tpl = this.renderRoot.querySelector('#tpl');
const clone = tpl.content.cloneNode(true);
this.renderRoot.appendChild(clone);
}
В таких случаях Lit не отслеживает изменения внутри вставленного фрагмента, и ответственность за обновление ложится на разработчика.
<template> напрямуюLit создаёт собственное представление шаблона, поскольку стандартный
<template>:
Lit анализирует строки шаблона, создаёт карту динамических частей и
затем использует DocumentFragment и NodePart
для точечного обновления DOM.
Шаблоны Lit кэшируются автоматически. Если два шаблона имеют
одинаковую структуру строк, они используют один и тот же внутренний
Template.
html`<p>${a}</p>`
html`<p>${b}</p>`
Оба выражения создают один шаблон, различаясь только данными. Это значительно снижает накладные расходы при повторных рендерах.
Некоторые ограничения принципиальны:
<${tag}>
недопустимо);Для вставки доверенного HTML используется директива
unsafeHTML, что подчёркивает потенциальную опасность
операции.
HTML-шаблоны являются центральным элементом Lit:
Элемент <template> остаётся вспомогательным
инструментом, тогда как шаблоны Lit формируют декларативный, реактивный
и высокопроизводительный слой представления.