Hyperapp — минималистичный JavaScript-фреймворк, ориентированный на создание быстрых и декларативных пользовательских интерфейсов. В его основе лежет концепция представления как функции, которая принимает состояние и возвращает описание интерфейса. Такой подход позволяет легко управлять UI, обновляя его при изменении состояния без прямой работы с DOM.
В Hyperapp представление описывается с помощью функции
view, которая получает текущее состояние приложения и
возвращает виртуальный DOM. Синтаксис напоминает JSX,
но в чистом Hyperapp используется объектная нотация:
const view = (state) =>
h("div", { id: "app" }, [
h("h1", {}, `Привет, ${state.name}`),
h("button", { onclick: state.changeName }, "Изменить имя")
]);
Здесь h — это функция создания виртуальных узлов
(hyperscript). Первым аргументом идет тег элемента, вторым
— объект атрибутов, третьим — содержимое или массив дочерних узлов.
Ключевые моменты:
view не изменяет DOM напрямую.Hyperapp поддерживает композицию представлений, что позволяет разделять интерфейс на независимые компоненты:
const Header = (props) =>
h("header", {}, h("h1", {}, props.title));
const Button = (props) =>
h("button", { onclick: props.onClick }, props.label);
const view = (state) =>
h("div", {}, [
Header({ title: "Мое приложение" }),
Button({ label: "Нажми меня", onClick: state.handleClick })
]);
Преимущества такого подхода:
В Hyperapp события привязываются через объект атрибутов, где обработчики вызывают действия (actions). Действие — это функция, которая изменяет состояние:
const state = { count: 0 };
const actions = {
increment: (value) => (state) => ({ count: state.count + value })
};
const view = (state, actions) =>
h("div", {}, [
h("h1", {}, `Счет: ${state.count}`),
h("button", { onclick: () => actions.increment(1) }, "Увеличить")
]);
Особенности:
Для динамических списков Hyperapp поддерживает ключи для элементов. Это важно для корректного обновления интерфейса при добавлении или удалении элементов:
const view = (state, actions) =>
h("ul", {}, state.items.map(item =>
h("li", { key: item.id }, item.text)
));
Значение ключей:
Hyperapp поддерживает работу с формами через события
oninput и onsubmit. Состояние формы
привязывается к свойствам состояния:
const state = { text: "" };
const actions = {
updateText: (value) => () => ({ text: value }),
submit: () => (state) => { console.log(state.text); return state; }
};
const view = (state, actions) =>
h("form", { onsubmit: (e) => { e.preventDefault(); actions.submit(); } }, [
h("input", { type: "text", value: state.text, oninput: (e) => actions.updateText(e.target.value) }),
h("button", { type: "submit" }, "Отправить")
]);
Особенности:
onsubmit
позволяет предотвратить стандартное поведение браузера.Стили и классы задаются через объект атрибутов:
h("div", { class: "container", style: { color: "red", fontSize: "20px" } }, "Пример")
Особенности:
class принимает строку с именами классов.style — объект, где ключи соответствуют свойствам CSS в
camelCase.h("div", { class: state.active ? "active" : "inactive" }, "Статус")
Hyperapp позволяет строить сложные интерфейсы с глубокой вложенностью компонентов без потери производительности:
const TodoItem = ({ item, toggle }) =>
h("li", { onclick: () => toggle(item.id) }, item.text);
const TodoList = ({ items, toggle }) =>
h("ul", {}, items.map(item => TodoItem({ item, toggle })));
Принципы:
Полноценное приложение строится по принципу:
Такой подход обеспечивает предсказуемость, простоту и масштабируемость интерфейсов, позволяя создавать интерактивные приложения с минимальными усилиями.