Haunted — это библиотека для создания веб-компонентов с использованием современного JavaScript. Она строится поверх нативных веб-компонентов и предоставляет реактивную модель, аналогичную React Hooks, что позволяет управлять состоянием и жизненным циклом компонентов лаконично и эффективно. Haunted минималистична и фокусируется на легкости и производительности, не требуя сложной инфраструктуры.
Компонент в Haunted определяется как функция, которая возвращает
шаблон с помощью html-тегов, импортируемых из
haunted. Стандартная структура компонента выглядит
следующим образом:
import { html, component } from 'haunted';
function MyComponent({ name }) {
return html`<p>Hello, ${name}!</p>`;
}
customElements.define('my-component', component(MyComponent));
Ключевые моменты:
component(MyComponent) оборачивает функцию в
веб-компонент, автоматически управляя рендерингом.html используется для безопасной генерации разметки с
поддержкой динамических данных.Haunted предлагает хук useState, аналогичный React:
import { useState } from 'haunted';
function Counter() {
const [count, setCount] = useState(0);
return html`
<p>Счёт: ${count}</p>
<button @click=${() => setCount(count + 1)}>Увеличить</button>
`;
}
customElements.define('counter-component', component(Counter));
Особенности использования useState:
useState может использоваться несколько раз для
управления разными переменными состояния.Haunted поддерживает хук useEffect для работы с
побочными эффектами:
import { useEffect } from 'haunted';
function Timer() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const interval = setInterval(() => setTime(new Date().toLocaleTimeString()), 1000);
return () => clearInterval(interval);
}, []);
return html`<p>Время: ${time}</p>`;
}
customElements.define('timer-component', component(Timer));
Особенности useEffect:
[]) задает зависимости; если массив
пуст, эффект выполняется один раз после монтирования.Haunted позволяет связывать свойства компонента с атрибутами HTML:
function Greeting({ name }) {
return html`<p>Привет, ${name}!</p>`;
}
customElements.define('greeting-component', component(Greeting));
В HTML можно использовать:
<greeting-component name="Мир"></greeting-component>
Правила:
События обрабатываются с помощью синтаксиса @event:
function Clicker() {
const [clicked, setClicked] = useState(false);
return html`
<button @click=${() => setClicked(!clicked)}>
${clicked ? 'Нажато' : 'Нажми меня'}
</button>
`;
}
customElements.define('clicker-component', component(Clicker));
Особенности:
Haunted поддерживает динамические шаблоны:
function List({ items }) {
return html`
<ul>
${items.map(item => html`<li>${item}</li>`)}
</ul>
`;
}
customElements.define('list-component', component(List));
Особенности:
html:${condition ? html`<p>Да</p>` : html`<p>Нет</p>`}
Компоненты Haunted легко комбинируются и переиспользуются. Один компонент может включать другой:
function App() {
return html`
<h1>Приложение</h1>
<greeting-component name="Haunted"></greeting-component>
<counter-component></counter-component>
`;
}
customElements.define('app-root', component(App));
Можно создавать собственные хуки для инкапсуляции логики:
import { useState, useEffect } from 'haunted';
function useToggle(initial = false) {
const [state, setState] = useState(initial);
const toggle = () => setState(!state);
return [state, toggle];
}
function ToggleButton() {
const [on, toggle] = useToggle();
return html`<button @click=${toggle}>${on ? 'Вкл' : 'Выкл'}</button>`;
}
customElements.define('toggle-button', component(ToggleButton));
Особенности пользовательских хуков:
Haunted можно использовать в уже существующих проектах без полной
перестройки. Компоненты могут рендериться в любые элементы DOM с помощью
render:
import { render, html } from 'haunted';
const root = document.getElementById('root');
render(html`<greeting-component name="Мир"></greeting-component>`, root);
Особенности:
Haunted минимизирует лишние рендеры и использует только нативные возможности браузера, что снижает нагрузку на память и CPU. Для оптимизации можно:
Haunted сочетает простоту и мощь реактивного программирования, позволяя создавать современные веб-компоненты с минимальными затратами кода и высокой производительностью. Весь цикл разработки — от состояния до жизненного цикла и событий — реализован через лаконичные и понятные хуки, обеспечивая чистую архитектуру и легкую масштабируемость проектов.