Haunted — это библиотека для создания веб-компонентов с использованием реактивных хуков, вдохновлённых React, но полностью построенных на стандартных веб-технологиях. Одной из ключевых концепций является работа с HTML-шаблонами, которые формируют структуру компонента и управляют его динамическим обновлением.
В Haunted шаблон обычно создаётся с помощью функции
html, импортируемой из самой библиотеки:
import { html, component } from 'haunted';
Функция html позволяет описывать структуру DOM с
использованием литеральных шаблонов (template literals). Всё, что
помещено внутрь `html```, превращается в реактивный
шаблон, который обновляется при изменении состояния
компонента.
Пример простого шаблона:
const MyComponent = () => {
return html`
<div class="container">
<h1>Привет, Haunted!</h1>
<p>Состояние компонента обновляется автоматически.</p>
</div>
`;
};
Здесь создаётся базовый DOM-структурированный блок, который при рендеринге вставляется в shadow DOM компонента.
Главная сила Haunted в том, что шаблоны могут включать
динамические выражения внутри ${}. Любая
переменная, функция или реактивное значение может быть вставлено
непосредственно в шаблон:
import { useState } from 'haunted';
const Counter = () => {
const [count, setCount] = useState(0);
return html`
<div>
<p>Счётчик: ${count}</p>
<button @click=${() => setCount(count + 1)}>Увеличить</button>
</div>
`;
};
Ключевые моменты:
count автоматически обновит текст в
<p>.<input type="text" value="${count}" />
Haunted обеспечивает тонкую реактивность: обновляются только те части DOM, которые реально изменились. Это достигается через «разметку шаблона» и механизм morphing DOM, где библиотека сравнивает старый и новый виртуальный DOM.
.map():const List = ({ items }) => html`
<ul>
${items.map(item => html`<li>${item}</li>`)}
</ul>
`;
Каждый элемент массива превращается в отдельный DOM-узел. При
изменении items Haunted обновляет только необходимые
<li>, не трогая остальной DOM.
Шаблоны Haunted позволяют назначать обработчики событий через
синтаксис @event:
const Button = () => html`
<button @click=${() => console.log('Клик!')}>Нажми меня</button>
`;
Особенности:
.addEventListener.Внутри шаблонов можно применять условные выражения напрямую:
const Greeting = ({ isLoggedIn }) => html`
<div>
${isLoggedIn
? html`<p>Добро пожаловать!</p>`
: html`<p>Пожалуйста, войдите</p>`}
</div>
`;
Такой подход минимизирует необходимость вручную управлять видимостью
элементов через display: none или
removeChild.
Haunted позволяет вставлять CSS прямо в шаблон через
<style>:
const StyledComponent = () => html`
<style>
p {
color: blue;
font-weight: bold;
}
</style>
<p>Стили применяются только внутри этого компонента.</p>
`;
<style> ограничены shadow DOM, что
предотвращает утечку CSS на страницу.const DynamicColor = ({ color }) => html`
<p style="color: ${color}">Текст с динамическим цветом</p>
`;
Шаблоны можно вложить друг в друга, создавая более сложные компоненты:
const Item = ({ name }) => html`<li>${name}</li>`;
const ItemList = ({ items }) => html`
<ul>
${items.map(item => html`${Item({ name: item })}`)}
</ul>
`;
Такой подход поддерживает переиспользуемость и декларативный стиль кода, сохраняя реактивность на уровне вложенных компонентов.
Для больших интерфейсов рекомендуется:
key при работе с массивами для минимизации
перестроения DOM.${},
чтобы ускорить рендеринг.Пример с ключами:
${items.map(item => html`<li key=${item.id}>${item.name}</li>`)}
HTML-шаблоны в Haunted предоставляют гибкую систему декларативного описания интерфейсов, где:
Шаблоны в Haunted формируют основу построения современного веб-компонента с минимальным количеством кода и высокой читаемостью.