Вложенные маршруты

В SkateJS маршрутизация реализуется через встроенные возможности компонентов и их реактивного обновления. Вложенные маршруты позволяют строить сложную структуру навигации, при которой один компонент может содержать несколько уровней маршрутов, управляемых в рамках одного приложения. Это особенно важно для приложений с большим количеством страниц и компонентов, где требуется поддержка иерархической навигации.

В SkateJS маршруты обычно задаются через объект router, который определяет соответствие между путём URL и компонентом. Для вложенных маршрутов этот объект может содержать вложенные объекты children, что позволяет создать дерево маршрутов.


Определение вложенных маршрутов

Простейший пример вложенного маршрута выглядит следующим образом:

import { define, Component, html } from 'skatejs';
import { Router } from 'skatejs-router';

class ChildPage extends Component {
  render() {
    return html`<p>Это дочерняя страница</p>`;
  }
}

define('child-page', ChildPage);

class ParentPage extends Component {
  render() {
    return html`
      <h2>Родительская страница</h2>
      <router-outlet></router-outlet>
    `;
  }
}

define('parent-page', ParentPage);

const routes = [
  {
    path: '/parent',
    component: 'parent-page',
    children: [
      {
        path: 'child',
        component: 'child-page'
      }
    ]
  }
];

const router = new Router({ routes });
router.start();

Ключевые моменты:

  • children определяет массив вложенных маршрутов.
  • Внутри родительского компонента используется <router-outlet> для рендеринга дочернего компонента.
  • Путь дочернего маршрута child интерпретируется относительно родительского /parent, формируя итоговый путь /parent/child.

Динамические параметры в вложенных маршрутах

В SkateJS возможно использование динамических сегментов маршрута с помощью двоеточия (:). Это позволяет создавать маршруты, параметры которых меняются в зависимости от URL.

const routes = [
  {
    path: '/users',
    component: 'users-page',
    children: [
      {
        path: ':id',
        component: 'user-detail'
      }
    ]
  }
];

При переходе на /users/42 компонент user-detail получит параметр id со значением 42. Параметры доступны через объект this.props.params внутри компонента:

class UserDetail extends Component {
  render() {
    const { id } = this.props.params;
    return html`<p>Пользователь ID: ${id}</p>`;
  }
}

Важный момент: вложенные маршруты автоматически наследуют контекст родителя, что позволяет строить сложные маршрутизируемые интерфейсы без дублирования кода.


Ленивая загрузка компонентов для вложенных маршрутов

Для оптимизации больших приложений можно использовать ленивую загрузку дочерних компонентов через динамический import. Это уменьшает первоначальный размер бандла и ускоряет старт приложения.

const routes = [
  {
    path: '/dashboard',
    component: 'dashboard-page',
    children: [
      {
        path: 'analytics',
        component: () => import('./analytics-page.js').then(m => m.default)
      }
    ]
  }
];

Особенности:

  • Вместо строки с названием компонента передается функция, возвращающая промис с модулем.
  • SkateJS автоматически загрузит компонент при первом переходе на маршрут analytics.
  • Ленивая загрузка особенно эффективна для редких или тяжёлых страниц.

Вложенные маршруты и состояние

SkateJS позволяет управлять состоянием маршрутов через реактивные свойства компонентов. Вложенные маршруты могут передавать данные между родителем и дочерним компонентом:

class ParentPage extends Component {
  static props = {
    user: String
  };

  render() {
    return html`
      <h2>Привет, ${this.user}</h2>
      <router-outlet .user=${this.user}></router-outlet>
    `;
  }
}

Вложенный компонент получает данные через привязку свойства .user, обеспечивая прямую связь состояния между уровнями маршрутов.


Навигация между вложенными маршрутами

Для перехода между вложенными маршрутами используется метод router.navigate(path):

this.router.navigate('/parent/child');

Важная деталь: путь всегда задается относительно корня, даже если маршруты вложенные. При этом <router-outlet> внутри родителя автоматически обновляет отображение дочернего компонента.


Обработка ошибок и fallback маршрутов

В SkateJS вложенные маршруты поддерживают маршруты по умолчанию и обработку ошибок:

const routes = [
  {
    path: '/parent',
    component: 'parent-page',
    children: [
      {
        path: 'child',
        component: 'child-page'
      },
      {
        path: '*',
        component: 'not-found'
      }
    ]
  }
];

Маршрут с path: '*' срабатывает, если ни один из дочерних маршрутов не совпал, позволяя отображать страницу 404 или аналогичный fallback.


Практические рекомендации

  • Использовать <router-outlet> только один раз на каждом уровне вложенности, чтобы избежать конфликтов рендеринга.
  • Для динамических параметров именовать свойства понятно и консистентно, чтобы дочерние компоненты легко получали нужные значения.
  • Ленивая загрузка компонентов оправдана для редко используемых страниц, но не для ключевых маршрутов, чтобы не создавать лишнюю задержку.
  • Планировать структуру вложенных маршрутов заранее, так как сложные деревья могут быстро стать трудно поддерживаемыми без четкой иерархии.

Вложенные маршруты в SkateJS позволяют создавать модульные и масштабируемые приложения с удобной иерархической навигацией, интеграцией реактивного состояния и поддержкой динамических параметров. Их правильное использование повышает читаемость кода и упрощает поддержку больших фронтенд-приложений.