Aguardando pelo Resultado de uma Navegação ā
Quando estiveres a usar o router-link
, a Vue Router chama o router.push
para acionar uma navegação. Enquanto o comportamento esperado para a maioria das ligações é navegar um utilizador para uma nova pÔgina, existem algumas situações onde os utilizadores continuarão na mesma pÔgina:
- Os utilizadores jÔ estão na pÔgina para qual estão a tentar navegar.
- Uma guarda de navegação aborta a navegação fazendo
return false
. - Uma nova guarda de navegação ocorre enquanto a anterior ainda não terminou.
- Uma guarda de navegação redireciona noutro lugar retornando uma nova localização (por exemplo,
return '/login'
). - Uma guarda de navegação lança um
Error
.
Se quisermos fazer alguma coisa depois de uma navegação for terminada, precisamos de uma maneira de esperar depois da chamada de router.push
. Suponha que temos um menu de dispositivo móvel que permite-nos ir para pÔginas diferentes e apenas queremos esconder o menu assim que tivermos navegado para a nova pÔgina, poderemos querer fazer alguma coisa como:
router.push('/my-profile')
this.isMenuOpen = false
router.push('/my-profile')
this.isMenuOpen = false
Mas isto fecharĆ” o menu imediatamente porque as navegaƧƵes sĆ£o assĆncronas, precisamos do wait
para esperar a promessa retornada pelo router.push
:
await router.push('/my-profile')
this.isMenuOpen = false
await router.push('/my-profile')
this.isMenuOpen = false
Agora o menu fecharÔ assim que a navegação for terminada mas também fecharÔ se a navegação foi impedida. Nós precisamos de uma maneira de detetar se realmente mudamos a pÔgina em que estamos ou não estamos.
Detetando Falhas de Navegação ā
Se uma navegação for impedida, resultando em o utilizador continuar na mesma pÔgina, o valor resolvido da Promise
retornada pelo router.push
serÔ uma Falha de Navegação. De outro modo, serÔ um valor falso ou melhor falsy
(normalmente undefined
). Isto permite-nos diferenciar o caso de onde navegamos a partir de onde estamos ou não estamos:
const navigationResult = await router.push('/my-profile')
if (navigationResult) {
// navegação impedida
} else {
// navegação bem-sucedida (isto inclui o caso de um redirecionamento)
this.isMenuOpen = false
}
const navigationResult = await router.push('/my-profile')
if (navigationResult) {
// navegação impedida
} else {
// navegação bem-sucedida (isto inclui o caso de um redirecionamento)
this.isMenuOpen = false
}
As falhas de navegação são instâncias de Error
com algumas propriedades adicionais que entregam-nos informações suficiente para saber qual navegação foi impedida e o porquê. Para verificar a natureza de um resultado de navegação, use a função isNavigationFailure
:
import { NavigationFailureType, isNavigationFailure } from 'vue-router'
// tentando sair da pÔgina de edição de um artigo sem o guardar
const failure = await router.push('/articles/2')
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
// mostrar uma pequena notificação para o utilizador
showToast('You have unsaved changes, discard and leave anyway?')
}
import { NavigationFailureType, isNavigationFailure } from 'vue-router'
// tentando sair da pÔgina de edição de um artigo sem o guardar
const failure = await router.push('/articles/2')
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
// mostrar uma pequena notificação para o utilizador
showToast('You have unsaved changes, discard and leave anyway?')
}
Dica
Se omitires o segundo parâmetro: isNavigationFailure(failure)
, ela apenas verifica se failure
é uma Falha de Navegação.
Diferenciando Falhas de Navegação ā
Conforme dissemos no inĆcio, existem situaƧƵes diferentes que abortam uma navegação, todas elas resultando em diferentes Falhas de Navegação. Eles podem ser diferenciados usando a isNavigationFailure
e o NavigationFailureType
. Existem trĆŖs tipos diferentes:
aborted
:false
foi retornado dentro de uma guarda de navegação para a navegação.cancelled
: Uma nova navegação ocorreu antes da navegação atual puder terminar, por exemplo, orouter.push
foi chamado enquanto espera dentro de uma guarda de navegação.duplicated
: A navegação foi impedida porque jÔ estamos localização de destino.
Propriedades das Falhas de Navegação ā
Todas as falhas de navegação expõem as propriedades to
e from
para refletir a localização atual bem como a localização de destino para a navegação que falhou:
// tentando acessar a pƔgina de administrador
router.push('/admin').then(failure => {
if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
failure.to.path // '/admin'
failure.from.path // '/'
}
})
// tentando acessar a pƔgina de administrador
router.push('/admin').then(failure => {
if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
failure.to.path // '/admin'
failure.from.path // '/'
}
})
Em todos casos, to
e from
são localizações de rota normalizadas.
Detetando Redirecionamentos ā
Quando estivermos a retornar uma nova localização dentro de uma Guarda de Navegação, estamos a acionar uma nova navegação que se sobrepõe aquela em curso. Diferentemente de outros valores de retorno, um redirecionamento não impede uma navegação, ele cria uma uma nova. Ele é portanto verificado de forma diferente, lendo a propriedade redirectedFrom
em uma Localização de Rota:
await router.push('/my-profile')
if (router.currentRoute.value.redirectedFrom) {
// `redirectedFrom` é uma localização de rota resolvida como `to` e `from` nas guardas de navegação
}
await router.push('/my-profile')
if (router.currentRoute.value.redirectedFrom) {
// `redirectedFrom` é uma localização de rota resolvida como `to` e `from` nas guardas de navegação
}