Universal Router в JavaScript использует подход на основе
промисов и динамической маршрутизации, что принципиально
отличается от классических роутеров типа react-router или
vue-router. Основные отличия:
<Route> или routes: [],
маршруты задаются как массив объектов с path,
action, children.Каждый маршрут в Universal Router имеет стандартную структуру:
const routes = [
{
path: '/users/:id',
action: ({ params, query }) => {
return fetchUser(params.id);
}
},
{
path: '/about',
action: () => 'Страница о приложении'
}
];
Ключевые элементы:
:id) или
регулярными выражениями для гибкой маршрутизации.React Router использует JSX-компоненты и декларативные маршруты:
<Route path="/users/:id" element={<User />} />
Для миграции на Universal Router:
Конвертация <Route> в
объект:
path берётся напрямую.element заменяется на action, которая
возвращает компонент или данные.Асинхронные данные: если компонент в React
Router загружал данные через useEffect, в Universal Router
это можно делать прямо в action с промисами.
Пример миграции:
// React Router
<Route path="/users/:id" element={<User />} />
// Universal Router
{
path: '/users/:id',
action: async ({ params }) => {
const user = await fetchUser(params.id);
return renderUserComponent(user);
}
}
Vue Router использует объект маршрутов с компонентами:
const routes = [
{ path: '/home', component: Home },
{ path: '/profile/:id', component: Profile }
];
Особенности миграции:
component заменяется на функцию
action.children) легко конвертируются
в children Universal Router.{
path: '/profile/:id',
action: async ({ params }) => {
const Profile = (await import('./Profile.js')).default;
return Profile(params.id);
}
}
В React и Vue Router часто используются <Navigate>
или next({ name: 'home' }). В Universal Router редиректы
реализуются через throw { redirect: '/path' }:
{
path: '/private',
action: ({ user }) => {
if (!user.isLoggedIn) {
throw { redirect: '/login' };
}
return 'Добро пожаловать';
}
}
Обработка ошибок делается через блок catch при вызове
метода router.resolve():
router.resolve({ pathname: '/private', user })
.then(result => render(result))
.catch(error => {
if (error.redirect) {
navigateTo(error.redirect);
} else {
renderError(error);
}
});
Universal Router передаёт параметры и query в объекте:
:id в
path.Пример:
{
path: '/search',
action: ({ query }) => {
return searchItems(query.q);
}
}
action.throw вместо встроенных методов фреймворка.router.resolve() вместо <Link> или
router.push().import UniversalRouter from 'universal-router';
import { fetchUser, fetchPosts } from './api';
const routes = [
{
path: '/',
action: () => 'Главная страница'
},
{
path: '/users/:id',
action: async ({ params }) => {
const user = await fetchUser(params.id);
if (!user) throw { redirect: '/' };
return user;
},
children: [
{
path: '/posts',
action: async ({ params }) => {
return fetchPosts(params.id);
}
}
]
}
];
const router = new UniversalRouter(routes);
router.resolve({ pathname: '/users/123/posts' })
.then(result => console.log(result))
.catch(err => console.error(err));
В этом примере показано, как конвертировать вложенные маршруты, использовать асинхронные данные и обрабатывать редиректы в стиле Universal Router, сохранив структуру и функциональность, аналогичную Vue или React Router.