Фреймворк Lit предоставляет набор встроенных
директив, которые позволяют управлять рендерингом шаблонов,
оптимизировать производительность и создавать динамический контент.
Директивы применяются внутри шаблонов, определяемых с помощью функции
html, и обеспечивают контроль над структурой DOM, стилями и
событиями.
repeat — рендеринг
списковДиректива repeat используется для эффективного
рендеринга массивов. Она особенно полезна при работе с большими
списками, так как позволяет минимизировать количество операций с DOM за
счет повторного использования существующих элементов.
import { html, LitElement } from 'lit';
import { repeat } from 'lit/directives/repeat.js';
class ItemList extends LitElement {
static properties = {
items: { type: Array }
};
render() {
return html`
<ul>
${repeat(
this.items,
item => item.id,
item => html`<li>${item.name}</li>`
)}
</ul>
`;
}
}
customElements.define('item-list', ItemList);
Ключевые моменты:
repeat значительно повышает производительность при
обновлении массивов, так как элементы с неизменным ключом не
перерисовываются.
ifDefined
— условная подстановка атрибутовДиректива ifDefined позволяет вставлять атрибут только
если значение не undefined. Это удобно при работе с
динамическими атрибутами.
import { html, LitElement } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
class ButtonLink extends LitElement {
static properties = {
href: { type: String }
};
render() {
return html`
<a href="${ifDefined(this.href)}">Ссылка</a>
`;
}
}
customElements.define('button-link', ButtonLink);
Если this.href равно undefined, атрибут
href не будет добавлен к элементу. Это предотвращает ошибки
и некорректное поведение ссылок.
guard — оптимизация
перерисовкиДиректива guard используется для предотвращения ненужной
перерисовки сложных шаблонов. Она принимает массив зависимостей и
шаблон, который будет перерендерен только при изменении
зависимостей.
import { html, LitElement } from 'lit';
import { guard } from 'lit/directives/guard.js';
class ExpensiveRender extends LitElement {
static properties = {
data: { type: Array }
};
render() {
return html`
${guard([this.data], () => html`
<ul>
${this.data.map(item => html`<li>${item}</li>`)}
</ul>
`)}
`;
}
}
customElements.define('expensive-render', ExpensiveRender);
Особенности:
asyncAppend
и asyncReplace — работа с асинхронными итераторамиЭти директивы позволяют рендерить контент по мере поступления данных из асинхронных источников.
asyncAppend добавляет новые элементы в конец списка без
перезаписи существующих.asyncReplace заменяет содержимое по мере поступления
новых данных.import { html, LitElement } from 'lit';
import { asyncAppend } from 'lit/directives/async-append.js';
class StreamList extends LitElement {
static properties = {
items: { type: Object } // асинхронный итератор
};
render() {
return html`
<ul>
${asyncAppend(this.items, item => html`<li>${item}</li>`)}
</ul>
`;
}
}
customElements.define('stream-list', StreamList);
Это особенно полезно для потоковых данных, таких как WebSocket-сообщения или асинхронные API-запросы.
classMap
и styleMap — динамическая привязка классов и стилейДирективы classMap и styleMap позволяют
управлять CSS-классами и inline-стилями на основе объекта.
import { html, LitElement } from 'lit';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
class StyledButton extends LitElement {
static properties = {
active: { type: Boolean },
color: { type: String }
};
render() {
const classes = { active: this.active, disabled: !this.active };
const styles = { backgroundColor: this.color, padding: '10px' };
return html`
<button class="${classMap(classes)}" style="${styleMap(styles)}">
Кнопка
</button>
`;
}
}
customElements.define('styled-button', StyledButton);
Преимущества:
live —
синхронизация с реальными значениямиДиректива live применяется для синхронизации значений
форм с реальным состоянием, предотвращая нежелательные сбросы при
обновлении шаблона.
import { html, LitElement } from 'lit';
import { live } from 'lit/directives/live.js';
class TextInput extends LitElement {
static properties = {
value: { type: String }
};
render() {
return html`
<input .value="${live(this.value)}">
`;
}
}
customElements.define('text-input', TextInput);
live гарантирует, что значение элемента формы не будет
перезаписано, если оно уже изменено пользователем.
unsafeHTML — вставка HTML-кода из строки (с
осторожностью, потенциально небезопасно).ref — получение ссылки на элемент внутри шаблона.until — отображение шаблона-заглушки до завершения
промиса.Эти директивы расширяют возможности Lit и позволяют создавать динамические, высокопроизводительные веб-компоненты с минимальным количеством кода.
Использование встроенных директив Lit обеспечивает гибкость, оптимизацию рендеринга и чистоту шаблонов, делая их мощным инструментом при построении сложных пользовательских интерфейсов.