Lit предоставляет высокоэффективный механизм рендеринга, основанный
на реактивных свойствах компонентов. Компонент, созданный с помощью
LitElement, автоматически отслеживает изменения своих
свойств и обновляет DOM только там, где это необходимо. Основной метод
рендеринга — render(), который возвращает шаблон, созданный
с использованием html-тегов из библиотеки
lit.
import { LitElement, html, css } from 'lit';
class MyComponent extends LitElement {
static properties = {
message: { type: String }
};
render() {
return html`<p>${this.message}</p>`;
}
}
customElements.define('my-component', MyComponent);
В данном примере любое изменение свойства message
автоматически инициирует повторный рендер только содержимого элемента
<p>. Lit использует шаблонное обновление, что
минимизирует количество изменений в DOM и повышает
производительность.
Свойства компонентов объявляются через статическое поле
properties. Каждое свойство может быть настроено с типом и
опциями:
type: автоматически конвертирует значения при
присвоении (например, String, Number,
Boolean, Array, Object).reflect: синхронизирует свойство с атрибутом элемента,
позволяя использовать CSS-селекторы и наблюдать изменения через
HTML.hasChanged: позволяет задать кастомную функцию
сравнения значений, контролируя, будет ли инициирован рендер.static properties = {
count: { type: Number, reflect: true, hasChanged: (newVal, oldVal) => newVal !== oldVal }
};
Если hasChanged возвращает false, рендер не
выполняется, даже при изменении значения свойства.
Процесс обновления компонента в Lit делится на несколько этапов:
Обновление свойств (update и
requestUpdate) Метод requestUpdate
инициирует проверку изменений и планирует рендер. При желании можно
вручную вызвать обновление:
this.requestUpdate('count', oldValue);Фаза подготовки (willUpdate) Метод
willUpdate(changedProperties) вызывается перед рендером.
Можно использовать для подготовки данных:
willUpdate(changedProperties) {
if (changedProperties.has('count')) {
console.log('count изменился');
}
}Рендеринг (render) Метод возвращает
шаблон, который будет отображён в Shadow DOM компонента. Lit использует
lit-html для дифференцированного обновления DOM, минимизируя
перерисовку.
Фаза завершения (updated) Метод
updated(changedProperties) вызывается после обновления DOM.
Часто используется для запуска побочных эффектов, таких как интеграция с
внешними библиотеками:
updated(changedProperties) {
if (changedProperties.has('count')) {
console.log(`Новое значение count: ${this.count}`);
}
}Для сложных компонентов с большим количеством данных Lit предлагает несколько способов оптимизации:
repeat, ifDefined и
guard:import { repeat } from 'lit/directives/repeat.js';
render() {
return html`
<ul>
${repeat(this.items, item => item.id, item => html`<li>${item.name}</li>`)}
</ul>
`;
}
Lit автоматически синхронизирует свойства и атрибуты, если указано
reflect: true. Это упрощает интеграцию с HTML и позволяет
использовать CSS-селекторы для изменения стилей в зависимости от
состояния.
static properties = {
active: { type: Boolean, reflect: true }
};
Установка this.active = true изменит атрибут
active на <my-component active>, а
удаление — на <my-component>.
Использование директив ifDefined и guard
позволяет управлять рендером на уровне отдельных узлов, предотвращая
лишние операции DOM:
import { guard } from 'lit/directives/guard.js';
render() {
return html`
${guard([this.items], () => html`
<ul>
${this.items.map(item => html`<li>${item}</li>`)}
</ul>
`)}
`;
}
Директива guard следит за зависимостями и пересоздаёт
шаблон только при изменении массива items.
Lit позволяет работать с событиями внутри компонентов без дополнительных библиотек:
render() {
return html`<button @click=${this._handleClick}>Нажать</button>`;
}
_handleClick() {
this.count++;
}
Событие изменяет реактивное свойство count, что
инициирует повторный рендер. При этом обновление происходит асинхронно,
что предотвращает лишние перерисовки при множественных изменениях.
Lit компоненты используют Shadow DOM по умолчанию, обеспечивая
изоляцию стилей. Для динамических изменений стилей можно использовать
свойства CSS или директиву styleMap:
import { styleMap } from 'lit/directives/style-map.js';
render() {
const styles = { color: this.active ? 'red' : 'black' };
return html`<p style=${styleMap(styles)}>Текст</p>`;
}
Это позволяет полностью контролировать отображение без прямого вмешательства в глобальные CSS.
Рендеринг в Lit строится вокруг реактивных свойств, минимальных обновлений DOM и удобных директив для динамического управления содержимым. Понимание жизненного цикла компонентов, оптимизации шаблонов и синхронизации свойств с атрибутами обеспечивает создание высокопроизводительных и поддерживаемых веб-компонентов.