Навигационные хуки в setup

В Vue Router навигационные хуки предоставляют мощный механизм для контроля переходов между маршрутами. При использовании Composition API с функцией setup они приобретают особую гибкость, позволяя работать с реактивными состояниями и эффектами напрямую внутри компонента. Рассмотрим ключевые аспекты их применения.


beforeRouteEnter

beforeRouteEnter срабатывает перед тем, как компонент будет создан. Важно, что внутри этого хука нет доступа к экземпляру компонента (this), так как компонент еще не создан. Вместо этого используется функция обратного вызова next, куда можно передать колбэк, который выполнится после создания компонента.

Пример в Composition API:

import { onBeforeMount } from 'vue';
import { useRouter } from 'vue-router';

export default {
  setup(props, { expose }) {
    const router = useRouter();

    const beforeEnter = (to, from, next) => {
      if (to.query.token) {
        next();
      } else {
        next({ name: 'login' });
      }
    };

    // В Composition API нужно использовать router.beforeEach на уровне приложения
    onBeforeMount(() => {
      router.beforeEach(beforeEnter);
    });
  }
};

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

  • Позволяет проверять параметры маршрута перед входом.
  • Не имеет доступа к реактивным данным компонента.
  • Для доступа к экземпляру компонента используют колбэк next(vm => { ... }).

beforeRouteUpdate

beforeRouteUpdate вызывается когда компонент уже создан, но маршрут изменяется. В Composition API доступ к этим событиям реализуется через onBeforeRouteUpdate из vue-router.

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

import { onBeforeRouteUpdate } from 'vue-router';
import { ref } from 'vue';

export default {
  setup() {
    const userId = ref(null);

    onBeforeRouteUpdate((to, from, next) => {
      userId.value = to.params.id;
      next();
    });

    return { userId };
  }
};

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

  • Можно изменять реактивные состояния компонента.
  • Полезен для обновления данных при изменении параметров маршрута без полной перезагрузки компонента.
  • Работает только внутри компонентов, связанных с маршрутом.

beforeRouteLeave

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

Пример в Composition API:

import { onBeforeRouteLeave } from 'vue-router';

export default {
  setup() {
    let hasUnsavedChanges = true;

    onBeforeRouteLeave((to, from, next) => {
      if (hasUnsavedChanges) {
        const answer = window.confirm('У вас есть несохраненные изменения. Продолжить?');
        if (answer) next();
        else next(false);
      } else {
        next();
      }
    });
  }
};

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

  • Можно блокировать переход с помощью next(false).
  • Удобен для предупреждений о несохраненных данных или для отмены навигации.
  • Работает напрямую с реактивными данными компонента.

onBeforeRouteEnter и onBeforeRouteLeave в Composition API

В версии Vue Router 4 появилась возможность вызывать хуки прямо внутри setup через функции onBeforeRouteEnter, onBeforeRouteUpdate и onBeforeRouteLeave. Это делает их использование более декларативным и интегрированным с Composition API.

Пример использования всех трёх хуков:

import { ref } from 'vue';
import { onBeforeRouteEnter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';

export default {
  setup() {
    const data = ref(null);

    onBeforeRouteEnter((to, from, next) => {
      console.log('Входим в маршрут', to.fullPath);
      next(vm => {
        vm.data = 'Загружено при входе';
      });
    });

    onBeforeRouteUpdate((to, from, next) => {
      console.log('Маршрут обновлен', to.params.id);
      data.value = `Обновлено для ID: ${to.params.id}`;
      next();
    });

    onBeforeRouteLeave((to, from, next) => {
      if (confirm('Вы уверены, что хотите уйти?')) next();
      else next(false);
    });

    return { data };
  }
};

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

  • Использовать хуки внутри setup только для компонентов, которые связаны с маршрутом. Для глобальной логики следует применять router.beforeEach и router.afterEach.
  • Работать с реактивными данными напрямую через Composition API, что позволяет избежать обращения к this.
  • Блокировка навигации с beforeRouteLeave полезна для форм и редактируемых данных.
  • Оптимизация запросов: beforeRouteUpdate позволяет повторно использовать компонент без полного уничтожения и создания, что снижает накладные расходы на загрузку данных.

Сравнение с Options API

Хук Options API Composition API
beforeRouteEnter beforeRouteEnter(to, from, next) onBeforeRouteEnter((to, from, next) => {})
beforeRouteUpdate beforeRouteUpdate(to, from, next) onBeforeRouteUpdate((to, from, next) => {})
beforeRouteLeave beforeRouteLeave(to, from, next) onBeforeRouteLeave((to, from, next) => {})

Преимущество Composition API — прямой доступ к реактивным состояниям и упрощённая интеграция с другими хуками Vue.