Unpoly — это прогрессивная библиотека для обновления частей страницы без полной перезагрузки. В отличие от классических SPA-фреймворков, Unpoly позволяет интегрировать динамическое поведение в существующие серверные шаблоны с минимальными изменениями. Организация кода в Unpoly строится вокруг селекторов, событий и слоёв обновления, что влияет на читаемость и поддержку приложения.
В Unpoly любое обновление страницы основано на фрагментах
HTML, которые обозначаются с помощью атрибута
up-target. Основные элементы:
up-target) —
определяет контейнер, который будет заменён содержимым ответа.up-href или form
с up-submit) — URL, с которого берётся HTML.up-transition) —
позволяют задавать визуальные переходы между старым и новым
содержимым.Пример корректной структуры кнопки для обновления списка без перезагрузки:
<button up-target="#user-list" up-href="/users" up-transition="fade">
Обновить список
</button>
<div id="user-list">
<!-- Контент будет заменён -->
</div>
Unpoly использует систему событий, позволяющую отделить логику взаимодействия от HTML. Основные события:
up:click — срабатывает при клике на элемент с
up-href.up:form:submit — срабатывает перед отправкой формы
через AJAX.up:fragment:loaded — вызывается после обновления
фрагмента на странице.События можно назначать через up.on() для глобальной
обработки:
up.on('up:fragment:loaded', '#user-list', (event) => {
console.log('Список пользователей обновлён', event.fragment);
});
Использование событий позволяет организовать код по зонам ответственности: обработчики для UI, данные и логика отдельных фрагментов не смешиваются с глобальной логикой страницы.
Unpoly поддерживает два подхода к обновлению фрагментов:
up-target, up-href, up-submit),
что снижает количество JS-кода и облегчает поддержку серверного
рендеринга.up.request()
для более сложных сценариев, например, когда нужно динамически менять
параметры запроса:up.request('/users', {
target: '#user-list',
method: 'GET',
transition: 'fade'
}).then(response => {
console.log('Фрагмент обновлён программно');
});
Программный подход полезен для компонентов, которые формируют параметры запроса на основе состояния JavaScript.
Для больших приложений рекомендуется разделять JS по фрагментам или
модулям компонентов, где каждый модуль отвечает за конкретный
контейнер (up-target).
Структура модуля фрагмента:
// user_list.js
export default function initUserList(fragment) {
const refreshButton = fragment.querySelector('[data-refresh]');
if (refreshButton) {
refreshButton.addEventListener('click', () => {
up.request('/users', { target: '#user-list', transition: 'fade' });
});
}
}
Подключение модуля через событие up:fragment:loaded:
import initUserList from './user_list.js';
up.on('up:fragment:loaded', '#user-list', (event) => {
initUserList(event.fragment);
});
Такой подход обеспечивает:
Unpoly облегчает обработку форм без полной перезагрузки. Основные элементы:
up-submit вместо стандартного
<form> позволяет отправлять форму через AJAX.up-target определяет, какой фрагмент заменяется после
ответа.up:form:submit, up:form:submitted).Пример:
<form up-submit="#user-list" action="/users" method="POST">
<input type="text" name="name">
<button type="submit">Добавить</button>
</form>
<div id="user-list"></div>
В JavaScript можно подписаться на событие отправки формы:
up.on('up:form:submitted', '#user-list', (event) => {
if (event.success) {
console.log('Форма успешно отправлена');
} else {
console.warn('Ошибка при отправке формы');
}
});
up.on('event', selector, handler) вместо прямой привязки к
элементам.Организация кода таким образом делает приложения на Unpoly поддерживаемыми, легко расширяемыми и совместимыми с серверными шаблонами.