Haunted — это библиотека для создания веб-компонентов на базе функциональных компонентов в стиле React, но с минимальным весом и использованием стандартного API Web Components. Она тесно интегрируется с библиотекой lit-html, которая отвечает за декларативное создание шаблонов HTML с возможностью реактивного обновления. Понимание синтаксиса lit-html является ключевым для эффективного использования Haunted.
html и
интерполяция данныхВ основе lit-html лежит тег-функция
html, которая позволяет создавать шаблоны HTML с поддержкой
динамических данных. Синтаксис следующий:
import { html, render } from 'lit-html';
const name = 'Alice';
const template = html`<p>Привет, ${name}!</p>`;
Ключевые моменты:
html`...` — это
тег-функция, а не обычный шаблонный литерал.${...}.Можно вставлять не только строки, но и целые элементы или другие шаблоны:
const items = ['яблоко', 'банан', 'вишня'];
const listTemplate = html`
<ul>
${items.map(item => html`<li>${item}</li>`)}
</ul>
`;
Lit-html различает атрибуты HTML и
свойства элементов. Для установки свойства используется
синтаксис .property=${value}:
const checked = true;
html`<input type="checkbox" .checked=${checked}>`;
Для установки атрибута используется синтаксис
attr=${value}:
const id = 'input1';
html`<input id=${id}>`;
Для событий используется префикс @:
html`<button @click=${() => console.log('Клик')}>Нажми</button>`;
Важно: использование правильного префикса предотвращает конфликт между атрибутами, свойствами и обработчиками событий.
Для условного рендеринга в lit-html применяются стандартные
JavaScript конструкции. Наиболее часто используют тернарный оператор или
логическое &&:
const isLoggedIn = true;
const template = html`
${isLoggedIn
? html`<p>Добро пожаловать!</p>`
: html`<p>Пожалуйста, войдите в систему.</p>`}
`;
Для сложных условий удобно выделять шаблоны в отдельные функции:
const greetingTemplate = (user) => html`
${user ? html`<p>Привет, ${user}!</p>` : html`<p>Привет, гость!</p>`}
`;
Для рендеринга списков используется метод map,
возвращающий массив шаблонов:
const todos = [
{ text: 'Купить молоко', done: false },
{ text: 'Написать статью', done: true },
];
const todoTemplate = html`
<ul>
${todos.map(todo => html`
<li class=${todo.done ? 'done' : ''}>${todo.text}</li>
`)}
</ul>
`;
Оптимизация обновлений: Lit-html использует
keyed updates только при использовании функции
repeat из пакета
lit-html/directives/repeat.js, что важно для динамических
списков.
Директивы позволяют расширять стандартный синтаксис шаблонов. Среди основных:
repeat — для оптимизированного
рендеринга списков.ifDefined — для условной установки
атрибутов.guard — предотвращает ненужное
пересоздание шаблонов при неизменных данных.asyncAppend и
asyncReplace — для работы с потоками данных.Пример использования repeat:
import { repeat } from 'lit-html/directives/repeat.js';
const items = [
{ id: 1, name: 'One' },
{ id: 2, name: 'Two' }
];
html`
<ul>
${repeat(items, item => item.id, item => html`<li>${item.name}</li>`)}
</ul>
`;
Первый аргумент — массив данных, второй — функция для ключа
(key), третий — функция для генерации шаблона элемента.
Шаблоны можно вкладывать друг в друга для модульного построения интерфейсов:
const card = (title, content) => html`
<div class="card">
<h3>${title}</h3>
<p>${content}</p>
</div>
`;
html`
<div>
${card('Заголовок 1', 'Содержимое 1')}
${card('Заголовок 2', 'Содержимое 2')}
</div>
`;
Такой подход повышает читаемость кода и упрощает поддержку больших компонентов.
В Haunted для отображения функциональных компонентов используется хук
useEffect совместно с html и
render. Пример минимального компонента:
import { component, html, useState } from 'haunted';
function Counter() {
const [count, setCount] = useState(0);
return html`
<div>
<p>Счёт: ${count}</p>
<button @click=${() => setCount(count + 1)}>Увеличить</button>
</div>
`;
}
customElements.define('my-counter', component(Counter));
Особенности взаимодействия Haunted с lit-html:
html из функционального компонента
обновляется автоматически при изменении состояния.html`<p>${data}</p>`.${...}..property=${value}, attr=${value}.@event=${handler}.&& или отдельные функции.map или
директиву repeat.Синтаксис lit-html сочетает лаконичность с высокой производительностью, а его грамотное использование в Haunted обеспечивает лёгкое создание динамических и реактивных веб-компонентов.