Lit — это легковесный JavaScript-фреймворк для создания веб-компонентов, основной упор в котором сделан на производительность и реактивность. Ключевым элементом его работы является система реактивных свойств, позволяющая автоматически отслеживать изменения данных и обновлять DOM без лишних операций.
Реактивные свойства в Lit объявляются с помощью статического свойства
properties или декоратора @property (при
использовании TypeScript или поддерживаемых инструментов). Каждое
свойство описывает:
type) — String, Number,
Boolean, Array, Object.reflect) —
синхронизация свойства с атрибутом DOM.hasChanged) —
функция для кастомной проверки изменения значения.Пример объявления через properties:
import { LitElement, html } from 'lit';
class MyComponent extends LitElement {
static properties = {
name: { type: String },
count: { type: Number, reflect: true },
active: { type: Boolean, hasChanged: (value, oldValue) => value !== oldValue }
};
constructor() {
super();
this.name = 'Lit';
this.count = 0;
this.active = false;
}
render() {
return html`
<p>${this.name} — ${this.count}</p>
<p>Active: ${this.active}</p>
`;
}
}
customElements.define('my-component', MyComponent);
В этом примере изменения count автоматически отражаются
на атрибуте DOM, а active проверяет изменение через функцию
hasChanged.
Основная логика работы реактивных свойств в Lit строится вокруг наблюдателей и очередей обновления:
hasChanged.update, который вызывает render.updated, позволяющий выполнить
побочные эффекты после обновления DOM.Это обеспечивает минимальное количество перерисовок и предотвращает лишние обновления при множественных изменениях свойств в одном цикле.
Если свойство объявлено с reflect: true, Lit
автоматически синхронизирует его значение с HTML-атрибутом. Это
позволяет:
Пример:
<my-component count="5"></my-component>
При загрузке страницы значение атрибута count будет
преобразовано в тип Number и установлено в свойство
count компонента.
hasChanged)Функция hasChanged(newValue, oldValue) позволяет задать
точный критерий изменения. По умолчанию Lit использует проверку
!==. Однако для сложных объектов или массивов может
потребоваться глубокое сравнение:
activeItems: {
type: Array,
hasChanged(newVal, oldVal) {
return JSON.stringify(newVal) !== JSON.stringify(oldVal);
}
}
Это особенно полезно, когда требуется реактивность на структурные изменения массивов и объектов.
Reactivity Lit поддерживает вычисляемые свойства, которые могут зависеть от других реактивных свойств. Реализация чаще всего делается через геттеры:
get status() {
return this.active ? 'Active' : 'Inactive';
}
Такое свойство не является реактивным самостоятельно, но при
изменении зависимого свойства active его значение
автоматически обновляется в шаблоне.
willUpdate(changedProperties) — вызывается перед
обновлением, с информацией о свойствах, которые изменились.update(changedProperties) — основной метод обновления,
можно переопределять для кастомной логики.updated(changedProperties) — вызывается после
завершения рендера, позволяет выполнять DOM-операции.Пример использования:
updated(changedProperties) {
if (changedProperties.has('count')) {
console.log(`Count изменился: ${this.count}`);
}
}
type,
чтобы Lit корректно преобразовывал значения из атрибутов.hasChanged — иначе компонент не будет отслеживать
изменения.render — лучше использовать вычисляемые
свойства.Система реактивных свойств делает Lit мощным инструментом для построения динамичных компонентов с минимальными накладными расходами и высокой производительностью.