В FAST Element маршрутизация и управление вложенными маршрутами реализуются через сочетание компонентов и реактивных свойств. Это позволяет создавать сложные интерфейсы с многоуровневой навигацией без лишнего дублирования кода. Основная идея заключается в том, что родительский компонент контролирует часть состояния маршрутов, а дочерние компоненты получают контекст и могут управлять своими собственными маршрутами.
FAST Element не содержит встроенного роутера, но для маршрутизации
часто используются сторонние решения, такие как @microsoft/fast-router
или кастомные реализации на основе window.history и
popstate. Маршруты определяются как объект, где ключи — это
пути, а значения — компоненты или функции, возвращающие компоненты:
const routes = {
"/": HomePage,
"/users": UsersPage,
"/users/:id": UserDetailPage
};
Для вложенных маршрутов структура маршрутов может быть иерархической:
const routes = {
"/users": {
component: UsersPage,
children: {
"/:id": UserDetailPage
}
}
};
В этом подходе родительский маршрут отвечает за рендеринг основного контейнера, а дочерний — за содержание внутри него.
Для реализации вложенных маршрутов обычно создаётся
контейнер-компонент, который рендерит дочерние маршруты. В FAST Element
это реализуется через reactive properties и шаблоны с
html:
import { FASTElement, html, css, customElement, observable } from "@microsoft/fast-element";
@customElement({ name: "user-page" })
export class UserPage extends FASTElement {
@observable userId;
static styles = css`
.container { padding: 20px; border: 1px solid #ccc; }
`;
connectedCallback() {
super.connectedCallback();
this.updateRoute(window.location.pathname);
window.addEventListener("popstate", () => this.updateRoute(window.location.pathname));
}
updateRoute(path) {
const match = path.match(/\/users\/(\d+)/);
this.userId = match ? match[1] : null;
}
render() {
return html`
Детали пользователя
${this.userId ? html` ` : html`Выберите пользователя
`}
`;
}
}
В этом примере:
userId реактивное (@observable) и
автоматически обновляет шаблон при изменении.updateRoute разбирает текущий путь и выделяет параметр
маршрута.user-detail рендерится только при
наличии параметра.Вложенные маршруты часто требуют передачи контекста от родителя к дочернему компоненту. В FAST Element это делается через свойства компонентов:
Для более сложных структур используется контекстное связывание, когда родительский компонент предоставляет данные, а дочерние компоненты подписываются на них через реактивные свойства или наблюдатели событий.
Переход между маршрутами реализуется через
history.pushState или сторонние роутеры:
function navigateToUser(userId) {
history.pushState({}, "", `/users/${userId}`);
window.dispatchEvent(new Event("popstate"));
}
При таком подходе родительский компонент автоматически поймает
событие popstate, обновит реактивные свойства и рендер
дочернего маршрута.
Для оптимизации часто используется динамический импорт дочерних компонентов:
async function loadUserDetail(userId) {
const module = await import("./user-detail.js");
const UserDetail = module.UserDetail;
const container = document.querySelector("user-page");
container.appendChild(new UserDetail({ id: userId }));
}
Это позволяет уменьшить размер начальной загрузки и инициализировать компоненты только при необходимости.
В FAST Element можно добавлять условные маршруты внутри родителя:
${this.userId
? html` `
: html`Выберите пользователя для просмотра деталей
`}
Использование тернарного оператора внутри шаблона позволяет динамически менять содержимое контейнера без перезагрузки страницы.