Хуки конкретных маршрутов beforeEnter

В Vue Router существует несколько уровней маршрутизируемых хуков: глобальные, локальные в компонентах и хуки конкретных маршрутов. Хук beforeEnter относится к последней категории и позволяет выполнять проверку или подготовку перед тем, как маршрут будет активирован. Его ключевая особенность заключается в том, что он применяется только к конкретному маршруту и не требует определения в компоненте.

Синтаксис и структура

Хук beforeEnter определяется внутри объекта маршрута при конфигурации Vue Router:

const routes = [
  {
    path: '/dashboard',
    component: Dashboard,
    beforeEnter: (to, from, next) => {
      // логика проверки
    }
  }
]

Аргументы функции:

  • to — объект маршрута, на который осуществляется переход.

  • from — объект маршрута, с которого осуществляется переход.

  • next — функция, определяющая дальнейший путь перехода:

    • next() — продолжить переход.
    • next(false) — отменить переход.
    • next('/path') — перенаправить на другой маршрут.
    • next({ name: 'routeName' }) — перенаправление с использованием имени маршрута.

Применение для проверки аутентификации

Частая задача для beforeEnter — проверка прав доступа пользователя перед отображением защищённого маршрута. Например:

const routes = [
  {
    path: '/admin',
    component: AdminPanel,
    beforeEnter: (to, from, next) => {
      const isAuthenticated = store.getters.isAuthenticated;
      const isAdmin = store.getters.isAdmin;
      if (isAuthenticated && isAdmin) {
        next();
      } else {
        next('/login');
      }
    }
  }
]

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

Асинхронная обработка в beforeEnter

beforeEnter поддерживает асинхронные операции. Часто требуется подгрузка данных или проверка состояния на сервере перед разрешением маршрута:

beforeEnter: async (to, from, next) => {
  try {
    const userData = await fetchUserData();
    if (userData.role === 'editor') {
      next();
    } else {
      next('/access-denied');
    }
  } catch (error) {
    next('/error');
  }
}

Важно корректно обрабатывать ошибки и обязательно вызывать next() либо с маршрутом, либо с false, чтобы не блокировать навигацию.

Ограничения и особенности

  • beforeEnter применяется только к маршруту, на котором он объявлен. Если используется вложенный маршрут, хуки родительского маршрута не вызываются автоматически для дочерних, если только дочерний маршрут явно не определён.
  • В отличие от глобальных хуков beforeEach, beforeEnter выполняется раньше рендеринга компонента, что позволяет предотвратить лишние действия и рендеринг.
  • Несколько хуков можно объединять через массив функций, если требуется модульная проверка:
beforeEnter: [
  authGuard,
  roleGuard
]

Где authGuard и roleGuard — отдельные функции, принимающие (to, from, next).

Различие с beforeRouteEnter в компоненте

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

Примеры использования

  1. Проверка параметров маршрута:
beforeEnter: (to, from, next) => {
  if (Number.isInteger(Number(to.params.id))) {
    next();
  } else {
    next('/not-found');
  }
}
  1. Перенаправление в зависимости от состояния приложения:
beforeEnter: (to, from, next) => {
  const hasCompletedSetup = store.getters.hasCompletedSetup;
  next(hasCompletedSetup ? '/dashboard' : '/setup');
}
  1. Логирование переходов для аналитики:
beforeEnter: (to, from, next) => {
  analytics.trackPageView(to.fullPath);
  next();
}

Рекомендации по использованию

  • Использовать beforeEnter для маршрутов с ограниченным доступом или необходимостью асинхронной проверки.
  • Если проверка требуется на нескольких маршрутах, стоит вынести её в отдельную функцию, чтобы избежать дублирования кода.
  • Для комплексных сценариев с несколькими уровнями вложенности можно сочетать beforeEnter с глобальными хуками beforeEach для более гибкого контроля навигации.

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