В Universal Router маршруты организуются в виде
дерева объектов, где каждый объект представляет отдельный маршрут с
набором свойств: path, action,
children и других. Каждый маршрут может иметь
родителя и потомков, что позволяет
создавать вложенные маршруты с разной степенью детализации.
Ключевые свойства маршрута:
path — строка, задающая шаблон URL. Поддерживаются
динамические сегменты через :param и регулярные
выражения.action — функция, вызываемая при совпадении маршрута.
Обычно возвращает компонент, данные или редирект.children — массив вложенных маршрутов, позволяющий
строить дерево навигации.name — опциональное имя маршрута, удобное для генерации
ссылок.Пример простого маршрута:
const routes = [
{
path: '/home',
action: () => 'Главная страница'
},
{
path: '/about',
action: () => 'О нас'
}
];
В Universal Router вложенность реализуется через
свойство children. Это позволяет создавать маршруты типа
/users/:id/profile, где /users/:id является
родителем, а profile — дочерним маршрутом.
const routes = [
{
path: '/users/:id',
action: ({ params }) => `Пользователь ${params.id}`,
children: [
{
path: 'profile',
action: ({ params }) => `Профиль пользователя ${params.id}`
},
{
path: 'settings',
action: ({ params }) => `Настройки пользователя ${params.id}`
}
]
}
];
Особенности вложенности:
path дочернего маршрута не должен начинаться с
/, иначе он будет рассматриваться как абсолютный.Динамические сегменты обозначаются двоеточием :. Они
захватывают значения из URL и передаются в объект params
функции action.
{
path: '/posts/:postId/comments/:commentId',
action: ({ params }) => `Пост ${params.postId}, комментарий ${params.commentId}`
}
Поддерживается использование регулярных выражений для более точного контроля над допустимыми значениями:
{
path: '/product/:id(\\d+)',
action: ({ params }) => `Продукт с ID ${params.id}`
}
Universal Router позволяет action быть асинхронной
функцией. Это полезно для загрузки данных перед рендерингом страницы или
компонента.
{
path: '/users/:id',
action: async ({ params }) => {
const response = await fetch(`/api/users/${params.id}`);
const data = await response.json();
return data;
}
}
Асинхронные маршруты полностью интегрируются с деревом: дочерние
маршруты будут ждать завершения родительской action, если
это необходимо.
match и resolveRoutematch: проверяет, соответствует ли
маршрут текущему URL. Используется внутри Universal Router для поиска
подходящего маршрута.resolveRoute: выполняет
action найденного маршрута и возвращает результат. Может
рекурсивно обрабатывать дочерние маршруты.Пример объединения вложенных маршрутов с асинхронной загрузкой:
const router = new UniversalRouter(routes);
router.resolve('/users/42/profile').then(result => {
console.log(result); // 'Профиль пользователя 42'
});
action можно вернуть объект
{ redirect: '/new-path' }.catch или маршрут с path '*'.const routes = [
{
path: '/old',
action: () => ({ redirect: '/new' })
},
{
path: '*',
action: () => 'Страница не найдена'
}
];
При больших приложениях дерево маршрутов можно структурировать по модулям:
import userRoutes from './userRoutes';
import adminRoutes from './adminRoutes';
const routes = [
{
path: '/',
action: () => 'Главная'
},
...userRoutes,
...adminRoutes
];
Каждый модуль может содержать свои вложенные маршруты, динамические
сегменты и асинхронные action. Это облегчает поддержку кода
и повышает читаемость.
action обеспечивают загрузку данных.Эта структура обеспечивает универсальный, расширяемый и предсказуемый механизм маршрутизации, подходящий как для простых SPA, так и для крупных приложений с множеством вложенных страниц и динамических данных.