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

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

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

В Vue.js вложенные маршруты задаются с помощью свойства children в объекте маршрута. Каждый маршрут может иметь дочерние маршруты, которые отображаются внутри родительского компонента с использованием <router-view>.

Пример структуры маршрутов:

import { createRouter, createWebHistory } from 'vue-router';
import Dashboard from '@/views/Dashboard.vue';
import Profile from '@/views/Profile.vue';
import Settings from '@/views/Settings.vue';
import Account from '@/views/Account.vue';
import Security from '@/views/Security.vue';

const routes = [
  {
    path: '/dashboard',
    component: Dashboard,
    children: [
      {
        path: 'profile',
        component: Profile
      },
      {
        path: 'settings',
        component: Settings,
        children: [
          {
            path: 'account',
            component: Account
          },
          {
            path: 'security',
            component: Security
          }
        ]
      }
    ]
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

В этом примере /dashboard является родительским маршрутом, а profile и settings — дочерними. Далее у settings есть собственные дочерние маршруты account и security.

Отображение дочерних маршрутов

Для того чтобы вложенные маршруты корректно отображались, в родительском компоненте необходимо разместить <router-view>. Это точка, в которой будут рендериться дочерние компоненты.

<template>
  <div>
    <h1>Dashboard</h1>
    <router-view></router-view>
  </div>
</template>

Если дочерние маршруты имеют свои собственные дочерние маршруты, <router-view> можно использовать несколько раз, создавая несколько уровней вложенности.

Путь к вложенным маршрутам

Путь к вложенному маршруту формируется от родительского маршрута. Например, маршрут /dashboard/settings/account соответствует следующей цепочке:

  • /dashboard → компонент Dashboard
  • /dashboard/settings → компонент Settings внутри Dashboard
  • /dashboard/settings/account → компонент Account внутри Settings

Свойство path дочернего маршрута не должно начинаться с /, иначе оно будет интерпретироваться как абсолютный путь, а не относительный к родителю.

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

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

{
  path: '/users/:userId',
  component: User,
  children: [
    {
      path: 'posts/:postId',
      component: Post
    }
  ]
}

В этом случае для доступа к параметрам можно использовать useRoute():

import { useRoute } from 'vue-router';

export default {
  setup() {
    const route = useRoute();
    console.log(route.params.userId);
    console.log(route.params.postId);
  }
};

Именованные маршруты и вложенность

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

{
  path: 'settings',
  name: 'Settings',
  component: Settings,
  children: [
    {
      path: 'security',
      name: 'Security',
      component: Security
    }
  ]
}

Навигация с использованием имен:

<router-link :to="{ name: 'Security', params: { userId: 123 } }">Security</router-link>

Lazy Loading дочерних компонентов

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

{
  path: 'profile',
  component: () => import('@/views/Profile.vue')
}

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

Редиректы и вложенные маршруты

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

{
  path: '/dashboard',
  component: Dashboard,
  redirect: '/dashboard/profile',
  children: [
    { path: 'profile', component: Profile },
    { path: 'settings', component: Settings }
  ]
}

При заходе на /dashboard пользователь автоматически попадет на /dashboard/profile.

Ограничение доступа к вложенным маршрутам

Для управления доступом применяются навигационные охранники (navigation guards). Они могут проверять авторизацию перед входом на дочерние маршруты:

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    const isAuthenticated = /* проверка авторизации */;
    if (!isAuthenticated) next('/login');
    else next();
  } else {
    next();
  }
});

Свойство meta удобно использовать для вложенных маршрутов:

{
  path: 'settings',
  component: Settings,
  meta: { requiresAuth: true }
}

Вложенные маршруты и именованные <router-view>

Для отображения нескольких дочерних компонентов одновременно можно использовать именованные <router-view>:

<template>
  <div>
    <router-view name="sidebar"></router-view>
    <router-view></router-view> <!-- default view -->
  </div>
</template>

Маршрут с назначением именованных вью:

{
  path: '/dashboard',
  components: {
    default: DashboardMain,
    sidebar: DashboardSidebar
  }
}

Это позволяет создавать сложные интерфейсы с постоянными панелями и динамическим контентом.

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