Unpoly — это JavaScript-библиотека, которая позволяет создавать быстрые и отзывчивые интерфейсы без необходимости полного SPA (Single Page Application). Она фокусируется на прогрессивном улучшении, подгружая части страниц динамически. Интеграция с фреймворками требует понимания, как Unpoly управляет DOM, событиями и состоянием страницы.
Фрагментная загрузка DOM Unpoly работает с
конкретными целевыми контейнерами (up-target) и подменяет
их содержимое через AJAX. Фреймворки, которые используют виртуальный DOM
(например, React или Vue), создают сложности, если Unpoly напрямую
заменяет элементы, управляемые этими фреймворками.
Ключевой момент: взаимодействовать нужно через
верхнеуровневые контейнеры, а не через внутренние элементы компонентов.
Например, вместо обновления конкретного div внутри
компонента React лучше перезагружать родительский компонент
целиком.
События жизненного цикла Unpoly генерирует собственные события для управления состоянием страницы:
up:fragment:loaded — фрагмент загружен и вставлен в
DOMup:fragment:revealed — фрагмент показан
пользователюup:fragment:removed — фрагмент удалёнЭти события можно использовать для инициализации компонентов фреймворка после того, как Unpoly обновил DOM. Например, в Vue можно заново монтировать компонент:
document.addEventListener('up:fragment:revealed', event => {
const container = event.target.querySelector('#vue-app');
if(container) {
new Vue({ el: container, data: { message: 'Обновлено' }});
}
});
Для React подход аналогичный: вызов ReactDOM.render или
createRoot(container).render(...) после подмены
фрагмента.
React управляет виртуальным DOM, а Unpoly напрямую подменяет реальные элементы. Чтобы избежать конфликтов:
up-target).up:fragment:revealed.Пример интеграции:
<div id="react-container" up-target>
<!-- React-компонент будет вставлен сюда -->
</div>
document.addEventListener('up:fragment:revealed', event => {
const container = event.target.querySelector('#react-container');
if(container) {
ReactDOM.createRoot(container).render(<App />);
}
});
Такой подход сохраняет реактивность и предотвращает конфликт с виртуальным DOM.
Vue-компоненты можно монтировать в фрагменты, подгружаемые Unpoly, аналогично React:
up-target) для
Vue-компонента.v-if и v-show внутри
компонента, чтобы управлять видимостью, не вмешиваясь в Unpoly.Пример:
document.addEventListener('up:fragment:revealed', event => {
const el = event.target.querySelector('#vue-app');
if(el) {
Vue.createApp({ data() { return { message: 'Фрагмент обновлён' }}}).mount(el);
}
});
Особенность: если Vue-компонент уже был смонтирован в старом DOM, необходимо удалить старый экземпляр перед монтированием нового, иначе возникнут ошибки реактивности.
Angular сильно зависит от зон и собственных механизмов рендеринга. Подмена DOM через Unpoly требует аккуратного подхода:
up-target.Пример динамического рендеринга:
document.addEventListener('up:fragment:revealed', event => {
const el = event.target.querySelector('#angular-app');
if(el) {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
}
});
Для многофрагментных страниц рекомендуется один корневой контейнер Angular и управление внутренними состояниями через маршрутизацию, а не прямые подмены Unpoly.
Для фреймворков без виртуального DOM интеграция проще:
up:fragment:loaded для повторной инициализации
плагинов.up-layer для модальных окон
или динамических панелей.Пример:
document.addEventListener('up:fragment:loaded', event => {
$(event.target).find('.datepicker').datepicker();
});
Таким образом, плагины повторно инициализируются после каждой загрузки фрагмента.
up:fragment:loaded и up:fragment:revealed
обеспечивают безопасную точку для инициализации.Unpoly позволяет прогрессивно улучшать интерфейсы без полной перезагрузки страницы, а грамотная интеграция с фреймворками строится на принципах изоляции, событий жизненного цикла и аккуратного монтирования компонентов. Реализация этих подходов обеспечивает корректную работу виртуальных DOM-фреймворков, динамических виджетов и плагинов, сохраняя преимущества Unpoly в быстроте и отзывчивости интерфейса.