Динамические редиректы

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

Использование функции для редиректа

В объекте маршрута свойство redirect может быть функцией, которая принимает объект маршрута и возвращает путь или объект маршрута для перенаправления:

const routes = [
  {
    path: '/user/:id',
    redirect: to => {
      const userId = to.params.id;
      return userId === 'admin' ? '/admin' : '/profile/' + userId;
    }
  },
  { path: '/admin', component: AdminComponent },
  { path: '/profile/:id', component: ProfileComponent }
];

Пояснения:

  • to — объект маршрута, включающий path, params, query и другую информацию.
  • Функция должна вернуть строку или объект маршрута.
  • Этот подход позволяет выполнять условные проверки перед редиректом.

Редиректы с объектом маршрута

Для более гибкой навигации можно возвращать объект маршрута с указанием name, params и query:

redirect: to => {
  if (!isLoggedIn()) {
    return { name: 'login', query: { redirect: to.fullPath } };
  } else {
    return { name: 'dashboard' };
  }
}
  • name указывает на именованный маршрут.
  • query позволяет сохранить информацию о предыдущем пути для последующего возврата.

Важные особенности

  1. Асинхронная проверка Функция редиректа может использовать асинхронные операции, например, проверку токена через API. В таком случае навигацию нужно обрабатывать через beforeEnter или глобальные beforeEach навигационные хуки, а не через прямой асинхронный редирект в redirect.

  2. Порядок маршрутов Редиректы обрабатываются в том порядке, в котором определены маршруты. Если есть пересечение путей, важно размещать более специфичные маршруты выше общих.

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

    {
      path: '/old-product/:id',
      redirect: to => `/product/${to.params.id}`
    }

    Это удобно при миграции структуры URL без изменения логики фронтенда.

Сравнение с beforeEnter

Редирект через redirect выполняется автоматически при сопоставлении маршрута. Если требуется более сложная логика с асинхронной проверкой или возможностью отмены навигации, используют хук beforeEnter:

{
  path: '/secret',
  beforeEnter: (to, from, next) => {
    if (hasAccess()) {
      next();
    } else {
      next({ name: 'login' });
    }
  }
}
  • next() без аргументов продолжает навигацию.
  • next({ path: '/login' }) выполняет редирект.
  • Позволяет асинхронно проверять состояние и управлять потоком переходов.

Рекомендации по структуре

  • Разделять статические и динамические редиректы для удобства поддержки.
  • Использовать именованные маршруты для возвращения объектов вместо строковых путей, чтобы изменения структуры URL не ломали редиректы.
  • Минимизировать сложную логику в функции редиректа, перемещая её в отдельные утилиты или сервисы проверки доступа.

Примеры комбинаций

  • Редирект с условием авторизации и сохранением запроса:
{
  path: '/private/:section',
  redirect: to => {
    return isLoggedIn()
      ? { name: 'section', params: { section: to.params.section } }
      : { name: 'login', query: { redirect: to.fullPath } };
  }
}
  • Редирект с проверкой параметров и замена устаревших URL:
{
  path: '/legacy/:id',
  redirect: to => {
    const newId = mapOldIdToNew(to.params.id);
    return { name: 'product', params: { id: newId } };
  }
}

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