Для начала работы с Universal Router в проекте на Vue необходимо установить библиотеку через npm или yarn:
npm install universal-router
или
yarn add universal-router
После установки создается основной маршрутный конфиг, представляющий
собой массив объектов с ключами path и action.
Каждый объект маршрута описывает соответствие URL и функцию обработки. В
контексте Vue действие маршрута обычно возвращает
компонент, который будет отображаться в корневом элементе
приложения.
import UniversalRouter from 'universal-router';
import Home from './components/Home.vue';
import About from './components/About.vue';
const routes = [
{ path: '/', action: () => Home },
{ path: '/about', action: () => About },
];
const router = new UniversalRouter(routes);
export default router;
В Vue 3 можно интегрировать Universal Router через реактивное состояние. Создается реактивная переменная для текущего компонента и функция для изменения маршрута при изменении URL:
import { createApp, reactive, h } from 'vue';
import router from './router';
const state = reactive({ currentRoute: null });
async function navigate(path) {
state.currentRoute = await router.resolve(path);
}
window.addEventListener('popstate', () => {
navigate(window.location.pathname);
});
navigate(window.location.pathname);
createApp({
render() {
return h(state.currentRoute);
}
}).mount('#app');
В этом примере каждый переход по URL обновляет
state.currentRoute, что автоматически вызывает перерисовку
компонента через реактивность Vue.
Universal Router поддерживает динамические сегменты
в пути с помощью синтаксиса :param:
const routes = [
{ path: '/user/:id', action: ({ params }) => ({ component: User, props: { id: params.id } }) },
];
Динамические параметры передаются в функцию action через
объект params. В Vue компонент можно передать эти параметры
через props, что позволяет компоненту получать нужные
данные напрямую.
Поддержка вложенных маршрутов реализуется с помощью массива
children в объекте маршрута:
const routes = [
{
path: '/dashboard',
action: () => Dashboard,
children: [
{ path: 'stats', action: () => Stats },
{ path: 'settings', action: () => Settings }
]
}
];
В этом случае URL /dashboard/stats активирует маршрут
Stats, а /dashboard/settings —
Settings. Universal Router автоматически строит иерархию
маршрутов и передает их в resolve.
Для изменения маршрута без перезагрузки страницы используется
history.pushState или аналогичные методы. Универсальный
роутер интегрируется с этим подходом через функцию навигации:
function goTo(path) {
window.history.pushState(null, '', path);
navigate(path);
}
Это позволяет создавать кнопки и ссылки с обработкой переходов на клиентской стороне, сохраняя работу реактивного состояния Vue.
Маршруты могут возвращать промисы, что удобно для подгрузки компонентов или данных:
const routes = [
{
path: '/posts/:id',
action: async ({ params }) => {
const module = await import('./components/Post.vue');
const data = await fetch(`/api/posts/${params.id}`).then(r => r.json());
return { component: module.default, props: { post: data } };
}
}
];
Асинхронная функция action позволяет загружать
компоненты по требованию и получать данные с сервера до отображения
страницы, что повышает производительность и уменьшает время первой
загрузки.
Universal Router поддерживает middleware-подход
через функцию resolve. Можно реализовать проверку прав
доступа или глобальные действия перед рендерингом компонента:
const router = new UniversalRouter(routes, {
resolveRoute(context, params) {
if (context.route.meta?.requiresAuth && !isAuthenticated()) {
return Login;
}
return context.route.action(context, params);
}
});
Ключ meta используется для хранения дополнительной
информации о маршруте, например, необходимости авторизации или роли
пользователя.
Query-параметры не являются частью пути, но доступны через объект
query. Их можно извлечь из URL и передать в компонент:
function parseQuery(search) {
return Object.fromEntries(new URLSearchParams(search));
}
window.addEventListener('popstate', () => {
const query = parseQuery(window.location.search);
navigate(window.location.pathname + window.location.search, { query });
});
В action query-параметры доступны для передачи в
компонент, что позволяет управлять состоянием страницы без изменения
маршрута.
Асинхронная загрузка компонентов повышает производительность крупных Vue-приложений:
const routes = [
{
path: '/lazy',
action: async () => {
const component = await import('./components/LazyComponent.vue');
return component.default;
}
}
];
Совмещение lazy-loading с динамическими маршрутами и асинхронной загрузкой данных делает Universal Router гибким инструментом для современных SPA.
Universal Router не хранит состояние истории или активного маршрута, это полностью контролируется приложением. Для интеграции с Vue можно использовать реактивные объекты, Vuex или Pinia:
import { reactive } from 'vue';
export const routeState = reactive({ current: null });
async function changeRoute(path) {
routeState.current = await router.resolve(path);
}
Таким образом создается централизованное хранилище текущего маршрута, доступное во всех компонентах через реактивные ссылки.
Universal Router предоставляет гибкую архитектуру для SPA на Vue, позволяя строить как простые маршруты, так и сложные многоуровневые структуры с асинхронными компонентами и динамическими параметрами.