Сбои при навигации

Добавлено в версии 3.4.0

При использовании router-link Vue Router вызывает router.push для запуска навигации. В большинстве случаев ожидаемое поведение ссылок заключается в переходе на новую страницу, но есть несколько ситуаций при которых пользователь остаётся на той же странице:

  • Пользователь уже находится на странице, на которую пытается перейти
  • Навигационный хук прерывает навигацию вызовом next(false)
  • Навигационный хук выбрасывает ошибку или вызывает next(new Error())

При использовании компонента router-link ни один из этих случаев не будет логироваться как ошибка. Однако при использовании router.push или router.replace можно столкнуться с сообщением "Uncaught (in promise) Error" после которого в консоли последует более конкретное сообщение. Давайте разберемся как отличать сбои навигации.

История вопроса

В версии 3.2.0, навигационные сбои доступны через два необязательных коллбэка router.push: onComplete и onAbort. Начиная с версии 3.1.0, router.push и router.replace возвращают Promise если не указаны коллбэки onComplete/onAbort. Этот Promise разрешается вместо вызова onComplete и отклоняется вместо вызова onAbort.

Обнаружение сбоев навигации

Сбой навигации будет экземпляром Error с парой дополнительных свойств. Проверить произошла ли ошибка в маршрутизаторе можно с помощью функции isNavigationFailure:

import { NavigationFailureType, isNavigationFailure } from 'vue-router'

// попытка перехода к странице администрирования
router
  .push('/admin')
  .catch(failure => {
    if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
      // отображение уведомления пользователю
      showToast('Необходимо авторизоваться для доступа к панели администрирования')
    }
  })

СОВЕТ

Если опустить второй параметр в isNavigationFailure(failure), то будет проверяться только, является ли ошибка сбоем навигации.

Тип NavigationFailureType

Тип NavigationFailureType поможет разработчикам определять тип навигационного сбоя. Существует 4 различных типа:

  • redirected: внутри навигационного хука был вызван next(newLocation) для перенаправления в другое место.
  • aborted: внутри навигационного хука был вызван next(false) для отмены навигации.
  • cancelled: произошла полностью новая навигация до того, как текущая могла закончиться. Например, во время ожидания внутри навигационного хука был вызван router.push.
  • duplicated: навигация была предотвращена, потому что уже находимся в месте назначения.

Свойства ошибок навигации

Все сбои навигации предоставляют доступ к свойствам to и from, чтобы отобразить текущее местоположение, а также местоположение места назначения для навигации, в которой произошёл сбой:

// попытка получения доступа к странице администрирования
router
  .push('/admin')
  .catch(failure => {
    if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
      console.log(failure.to.path) // '/admin'
      console.log(failure.from.path) // '/'
    }
  })

Во всех случаях значения to и from будут объектами нормализованных маршрутов.