Haunted — это минималистичная библиотека для создания веб-компонентов с использованием реактивного подхода, вдохновлённого React Hooks. Одной из ключевых возможностей при построении интерфейсов является условный рендеринг, позволяющий изменять отображение DOM в зависимости от состояния компонента.
В Haunted условный рендеринг достигается через стандартные механизмы Jav * aScript: тернарные операторы, логические выражения и функции, возвращающие шаблоны.
Тернарный оператор является самым распространённым способом управлять
условным отображением. В Haunted он используется внутри шаблонов,
создаваемых с помощью html из haunted.
import { html, component } from 'haunted';
import { useState } from 'haunted';
function UserStatus() {
const [loggedIn, setLoggedIn] = useState(false);
return html`
<div>
${loggedIn
? html`<p>Пользователь вошёл в систему</p>`
: html`<p>Пользователь не авторизован</p>`}
<button @click=${() => setLoggedIn(!loggedIn)}>
${loggedIn ? 'Выйти' : 'Войти'}
</button>
</div>
`;
}
customElements.define('user-status', component(UserStatus));
Ключевые моменты:
${} может возвращать другой шаблон
`html```, создавая вложенные структуры.loggedIn управляется через
useState, что обеспечивает реактивное обновление DOM при
изменении значения.Для простых условий можно использовать логические операторы
&& и ||. Они позволяют сократить код,
когда нужно отобразить элемент только при истинном значении условия.
function Notification({ message }) {
return html`
<div>
${message && html`<p>Новое уведомление: ${message}</p>`}
</div>
`;
}
customElements.define('notification-message', component(Notification));
Особенности:
message равно null или
undefined, блок не рендерится.Когда условия становятся сложными, логично выносить рендеринг в отдельные функции. Это повышает читаемость и упрощает поддержку кода.
function renderContent(type) {
switch(type) {
case 'loading':
return html`<p>Загрузка...</p>`;
case 'error':
return html`<p>Произошла ошибка</p>`;
case 'success':
return html`<p>Данные успешно загружены</p>`;
default:
return html``;
}
}
function DataStatus() {
const [status, setStatus] = useState('loading');
return html`
<div>
${renderContent(status)}
<button @click=${() => setStatus('success')}>Загрузить</button>
</div>
`;
}
customElements.define('data-status', component(DataStatus));
Преимущества подхода:
Haunted позволяет рендерить несколько элементов одновременно с помощью массивов или `html`` шаблонов внутри тернарного оператора.
function TodoList({ todos }) {
return html`
<ul>
${todos.length === 0
? html`<li>Список пуст</li>`
: todos.map(todo => html`<li>${todo}</li>`)}
</ul>
`;
}
customElements.define('todo-list', component(TodoList));
Особенности:
map используется для динамического создания
элементов списка.Условный рендеринг не ограничивается только содержимым. Атрибуты элементов также можно изменять динамически.
function Button({ disabled }) {
return html`
<button ?disabled=${disabled}>
${disabled ? 'Недоступно' : 'Нажми меня'}
</button>
`;
}
customElements.define('dynamic-button', component(Button));
Синтаксис ?attr=${value}:
useState или useReducer. Это
обеспечивает автоматическое обновление DOM при изменении данных.Условный рендеринг в Haunted сочетает мощь реактивных хуков с лаконичностью шаблонов `html``. Тернарные операторы, логические выражения и функции позволяют гибко управлять отображением интерфейса, создавая динамичные и отзывчивые веб-компоненты.