Universal Router — это современная библиотека маршрутизации для JavaScript, предназначенная для управления навигацией в веб-приложениях. Одной из ключевых особенностей является способность отслеживать историю переходов и управлять навигационными событиями без привязки к конкретной платформе или фреймворку.
История переходов (history) — это объект, который
хранит последовательность переходов пользователя между маршрутами.
Universal Router не навязывает конкретную реализацию истории, позволяя
использовать как встроенный объект window.history, так и
сторонние реализации (например, history из пакета
history).
Каждый переход содержит следующие ключевые элементы:
?.#.Эти элементы позволяют полностью воспроизвести состояние приложения при навигации вперед и назад.
Universal Router интегрируется с объектами истории через методы:
n шагов вперед или назад.Пример использования с нативным window.history:
router.resolve({ pathname: '/about' })
.then(() => {
window.history.pushState({ page: 'about' }, '', '/about');
});
Universal Router позволяет обрабатывать маршруты асинхронно. При этом каждый переход может быть отложен до завершения промиса:
const router = new UniversalRouter(routes, {
context: {},
resolveRoute(context, params) {
return new Promise(resolve => {
setTimeout(() => resolve(`Маршрут ${context.pathname} загружен`), 300);
});
}
});
router.resolve({ pathname: '/dashboard' }).then(result => console.log(result));
Асинхронные переходы интегрируются с историей, что позволяет корректно сохранять состояние приложения даже при длительных загрузках данных.
История переходов поддерживает подписку на события. В стандартной
реализации браузера используется событие popstate, которое
вызывается при переходах назад и вперед. Универсальный подход позволяет
создавать кастомные подписки:
window.addEventListener('popstate', event => {
router.resolve({ pathname: window.location.pathname });
});
Каждое событие предоставляет доступ к состоянию перехода через
event.state, что облегчает восстановление контекста
маршрута.
Universal Router не ограничен встроенной историей браузера. Для серверного рендеринга или нестандартных приложений можно реализовать собственный объект истории с необходимыми методами:
class MemoryHistory {
constructor() {
this.stack = [];
this.index = -1;
}
push(path) {
this.stack = this.stack.slice(0, this.index + 1);
this.stack.push(path);
this.index++;
}
back() {
if (this.index > 0) this.index--;
}
forward() {
if (this.index < this.stack.length - 1) this.index++;
}
current() {
return this.stack[this.index];
}
}
const memoryHistory = new MemoryHistory();
memoryHistory.push('/home');
memoryHistory.push('/profile');
memoryHistory.back();
console.log(memoryHistory.current()); // /home
Такой подход обеспечивает полный контроль над историей и делает маршрутизацию независимой от платформы.
Одним из преимуществ Universal Router является возможность хранить данные состояния вместе с переходами. Это позволяет реализовать:
Пример:
window.history.pushState({ formData: { name: 'Иван' } }, '', '/form');
При обработке события popstate состояние можно
восстановить:
window.addEventListener('popstate', event => {
const data = event.state?.formData;
if (data) {
document.querySelector('input[name="name"]').value = data.name;
}
});
История переходов тесно связана с логикой маршрутов в Universal Router. Каждый маршрут может использовать состояние истории для принятия решений о редиректах, асинхронной загрузке данных или анимации перехода. Это создаёт гибкую систему навигации, где маршруты и история работают как единый механизм управления состоянием приложения.
Такой подход делает Universal Router мощным инструментом для построения веб-приложений с динамической навигацией и полной поддержкой истории переходов.