Хуки внутри компонентов beforeRouteLeave

В библиотеке Vue Router хуки жизненного цикла маршрутов предоставляют мощные средства для управления переходами между страницами и компонентами. Один из наиболее полезных хуков на уровне компонента — это beforeRouteLeave. Он позволяет контролировать, что происходит перед покиданием компонента, и является ключевым инструментом для предотвращения потери данных или реализации дополнительных проверок перед переходом.


Основное назначение beforeRouteLeave

Хук beforeRouteLeave вызывается перед тем, как текущий компонент будет удален из DOM при переходе на другой маршрут. Его использование оправдано в ситуациях, когда требуется:

  • Предотвратить случайный уход пользователя с незавершённой формой.
  • Сохранить состояние компонента перед его уничтожением.
  • Запросить подтверждение действия у пользователя.

Сигнатура хука выглядит следующим образом:

beforeRouteLeave(to, from, next) {
  // Логика перед переходом
}

Где параметры:

  • to — объект маршрута, на который происходит переход.
  • from — объект текущего маршрута, с которого осуществляется переход.
  • next — функция для продолжения или отмены перехода.

Управление переходом

next может принимать несколько вариантов использования:

  1. Продолжить переход
next()

Переход выполняется без ограничений.

  1. Отменить переход
next(false)

Маршрут не меняется, компонент остаётся на месте.

  1. Перенаправление на другой маршрут
next({ path: '/other' })

Переход осуществляется на указанный маршрут.

Использование этих вариантов позволяет гибко управлять логикой перед уходом с компонента.


Пример защиты формы от потери данных

export default {
  data() {
    return {
      formChanged: false
    };
  },
  methods: {
    onInput() {
      this.formChanged = true;
    }
  },
  beforeRouteLeave(to, from, next) {
    if (this.formChanged) {
      const answer = window.confirm('Есть несохраненные изменения. Вы уверены, что хотите покинуть страницу?');
      if (answer) {
        next();
      } else {
        next(false);
      }
    } else {
      next();
    }
  }
};

В этом примере хук проверяет состояние formChanged и при необходимости блокирует переход, предотвращая потерю несохранённых данных.


Особенности работы в компонентах с keep-alive

Если компонент обёрнут в <keep-alive>, beforeRouteLeave всё равно вызывается при переходе на другой маршрут, но компонент не уничтожается полностью. Это позволяет комбинировать кэширование компонента и управление переходом:

  • activated — вызывается при повторной активации компонента.
  • deactivated — вызывается при временном скрытии компонента.

Таким образом, можно одновременно хранить состояние и контролировать уход пользователя.


Асинхронные операции внутри beforeRouteLeave

Хук поддерживает асинхронность через промисы или колбэки. Это особенно полезно для отправки данных на сервер перед переходом:

beforeRouteLeave(to, from, next) {
  saveDraft()
    .then(() => {
      next();
    })
    .catch(() => {
      next(false);
    });
}

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


Важные рекомендации

  • Не использовать beforeRouteLeave для глобального контроля маршрутов — для этого существуют глобальные хуки.
  • Проверять состояние только локальных данных компонента.
  • Избегать долгих синхронных операций, блокирующих интерфейс — лучше использовать асинхронные подходы с промисами.
  • Всегда вызывать next в конце логики, иначе переход останется заблокированным.

Совместимость с Vue 3 и Vue Router 4

В Vue 3 и Vue Router 4 хук сохраняет ту же сигнатуру, но рекомендуется использовать Composition API для более чистой интеграции:

import { onBeforeRouteLeave } from 'vue-router';

setup() {
  const formChanged = ref(false);

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

  return { formChanged };
}

Такой подход позволяет использовать реактивные переменные и полностью соответствовать стилю Composition API, делая код более модульным и тестируемым.


beforeRouteLeave — один из самых эффективных инструментов Vue Router для контроля ухода с компонента. Он сочетает простоту синтаксиса с высокой гибкостью, поддерживая как синхронные, так и асинхронные сценарии, а также полностью совместим с современными подходами Vue 3.