Ожидание результата навигации
При использовании router-link, Vue Router вызывает router.push для запуска навигации. Хотя ожидаемое поведение для большинства ссылок — перенаправление пользователя на новую страницу, есть несколько ситуаций, в которых пользователи останутся на той же странице:
- Пользователь уже находится на странице, на которую он пытается перейти.
- Защита навигации navigation guard прерывает навигацию, выполняя
return false. - Новая защита навигации срабатывает, пока предыдущая не завершилась.
- Защита навигации navigation guard перенаправляет на другую страницу, возвращая новое местоположение (например,
return '/login'). - Защита навигации navigation guard выбрасывает
Error.
Если нужно выполнить какое-то действие после завершения навигации, необходимо дождаться завершения вызова router.push. Представьте, что у нас есть мобильное меню, позволяющее переходить на разные страницы, и мы хотим скрыть меню только после перехода на новую страницу. В таком случае можно сделать так:
router.push('/my-profile')
this.isMenuOpen = false
Но это закроет меню сразу же, так как навигация асинхронная. Нам нужно await промис, возвращаемый router.push:
await router.push('/my-profile')
this.isMenuOpen = false
Теперь меню закроется после завершения навигации, а также при её прерывании. Нам нужен способ определить, действительно ли мы перешли на другую страницу или нет.
Обнаружение ошибок навигации
Если навигация прерывается, и пользователь остаётся на той же странице, результирующее значение Promise , возвращаемого router.push, будет ошибкой навигации. В противном случае, это будет ложное значение (обычно undefined). Это позволяет нам различать случаи, когда мы перешли на другую страницу, или нет:
const navigationResult = await router.push('/my-profile')
if (navigationResult) {
// navigation prevented
} else {
// navigation succeeded (this includes the case of a redirection)
this.isMenuOpen = false
}
Ошибки навигации — это Error экземпляры с несколькими дополнительными свойствами, которые предоставляют достаточную информацию для понимания причины прерывания навигации. Чтобы проверить характер результата навигации, используйте функцию isNavigationFailure:
import { NavigationFailureType, isNavigationFailure } from 'vue-router'
// trying to leave the editing page of an article without saving
const failure = await router.push('/articles/2')
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
// show a small notification to the user
showToast('You have unsaved changes, discard and leave anyway?')
}
СОВЕТЕсли вы опустите второй параметр:
isNavigationFailure(failure), то он будет только проверять, является лиfailureошибкой навигации.
Различение ошибок навигации
Как уже говорилось, существуют разные ситуации, прерывающие навигацию, которые все приводят к разным ошибкам навигации. Они могут быть различимы с помощью isNavigationFailure и NavigationFailureType. Существует три типа:
-
aborted:falseбыло возвращено в рамках защиты навигации для навигации. -
cancelled: Новая навигация произошла до завершения текущей навигации. Например,router.pushбыл вызван во время ожидания внутри защиты навигации. -
duplicated: Навигация была прервана, потому что мы уже находимся на целевой странице.
Свойства ошибок навигации
Все ошибки навигации предоставляют свойства to и from для отражения текущего и целевого местоположения для произошедшей ошибки навигации:
// trying to access the admin page
router.push('/admin').then(failure => {
if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
failure.to.path // '/admin'
failure.from.path // '/'
}
})
Во всех случаях to и from — нормализованные местоположения маршрутов.
Обнаружение перенаправлений
При возвращении нового местоположения внутри защиты навигации, мы запускаем новую навигацию, которая перекрывает текущую. В отличие от других возвращаемых значений, перенаправление не прерывает навигацию, а создает новую. Поэтому оно проверяется по-другому, считывая свойство redirectedFrom в местоположении маршрута:
await router.push('/my-profile')
if (router.currentRoute.value.redirectedFrom) {
// redirectedFrom is resolved route location like to and from in navigation
// guards
}
© 2013–present Evan You
Licensed under the MIT License.
https://next.router.vuejs.org/guide/advanced/navigation-failures