Навигация
В роутере есть два способа менять адрес:
route.open(payload)открывает конкретный роут;router.navigate(payload)записывает путь или query в history напрямую.
Обычно лучше вызывать route.open: так код остается привязан к роуту, а не к строке URL. router.navigate нужен для низкоуровневых случаев: поменять только query, перейти по уже готовому пути, вызвать back/forward.
Открытие роута
В коде приложения роут запускается в нужном scope:
import { scoped } from "@virentia/core";
import { profileRoute } from "./routes";
await scoped(appScope, () =>
profileRoute.open({
params: { id: 42 },
query: { tab: "posts" },
}),
);Если роут зарегистрирован в роутере с history, route.open соберет URL из шаблона пути и запишет его в history. Если history не подключена, роут все равно запустит предзагрузчики и beforeOpen.
replace заменяет текущую запись history:
await scoped(appScope, () =>
profileRoute.open({
params: { id: 42 },
replace: true,
}),
);Прямая навигация
router.navigate пишет URL напрямую:
await scoped(appScope, () =>
router.navigate({
path: "/users/42",
query: { tab: "posts" },
}),
);Если path не передан, сохраняется текущий путь и меняется только query:
await scoped(appScope, () =>
router.navigate({
query: { dialog: "invite" },
}),
);back и forward вызывают соответствующие методы history-адаптера:
await scoped(appScope, () => router.back());
await scoped(appScope, () => router.forward());Ссылки в React
Link рендерит <a>, строит href из зарегистрированного роута и при обычном клике вызывает route.open:
import { Link } from "@virentia/router-react";
<Link to={profileRoute} params={{ id: 42 }} query={{ tab: "posts" }}>
Profile
</Link>Клики с клавишами-модификаторами, уже отмененные клики и ссылки с target не равным _self остаются браузеру.
useLink нужен компонентам дизайн-системы, которым надо получить href и готовую функцию открытия:
const { path, open } = useLink(profileRoute, { id: 42 });Тесты и системные границы
allSettled удобен там, где надо явно указать scope и дождаться всей асинхронной работы графа:
await allSettled(profileRoute.open, {
scope: appScope,
payload: { params: { id: 42 } },
});Такая форма подходит для тестов, серверных загрузчиков, команд и адаптеров. В обычном коде приложения чаще читается проще:
await scoped(appScope, () => profileRoute.open({ params: { id: 42 } }));Частые сценарии
Открыть страницу сущности:
profileRoute.open({ params: { id: 42 } });Открыть вкладку через query:
profileRoute.open({
params: { id: 42 },
query: { tab: "activity" },
});Сделать перенаправление из проверки:
createRoute({
path: "/admin",
beforeOpen: [
async () => {
if (!session.isAdmin.value) {
await homeRoute.open({ replace: true });
}
},
],
});Оставить путь и поменять query:
router.navigate({
query: { filter: "open" },
});