Eu tenho a seguinte sequência acontecendo:
Tela principal
Tela de carregamento
Tela de resultados
Na página inicial, quando alguém clica em um botão, eu os envio para a tela de carregamento, através de:
this.$router.push({path: "/loading"});
E quando a tarefa termina, eles são enviados para a tela de resultados via
this.$router.push({path: "/results/xxxx"});
O problema é que, geralmente, eles querem ir dos resultados para a tela principal, mas quando clicam, são enviados para o carregamento novamente, o que os envia de volta aos resultados, para que fiquem presos em um loop infinito e incapazes de ir de volta à tela principal.
Alguma idéia de como corrigir isso? Idealmente, eu gostaria que houvesse uma opção como:
this.$router.push({path: "/loading", addToHistory: false});
que os enviaria para a rota sem adicioná-la ao histórico.
fonte
this.$router.replace({path: "/results/xxxx"})
$router.replace
de Loading. Isso agora me permite voltar de Resultados -> Principal, mas não consigo avançar para os resultados.Respostas:
Existe uma maneira perfeita de lidar com essa situação
Você pode usar a proteção no componente para controlar a rota no nível de grânulos
Faça as seguintes alterações no seu código
No componente da tela principal
No carregamento do componente da tela
No componente da tela de resultado
Acabei de criar um pequeno aplicativo vue para reproduzir o mesmo problema. Funciona no meu local conforme sua pergunta. Espero que ele resolva seu problema também.
fonte
Eu acho que
router.replace
é o caminho a percorrer - mas ainda algumas linhas de pensamento (não testadas):Basicamente, na
$router
mudança, ele renderiza o componente de carregamento até que seja emitidoload:stop
;router-view
fonte
Essa é uma decisão difícil, considerando o pouco que sabemos sobre o que está ocorrendo em sua rota de carregamento.
Mas...
Eu nunca tive a necessidade de criar uma rota de carregamento, apenas carregando componentes que são renderizados em várias rotas durante o estágio de coleta de dados / init.
Um argumento para não ter uma rota de carregamento seria que um usuário poderia navegar diretamente diretamente para esse URL (acidentalmente) e, em seguida, parece que não teria contexto suficiente para saber para onde enviar o usuário ou que ação tomar. Embora isso possa significar que ele cai em uma rota de erro neste momento. No geral, não é uma ótima experiência.
Outra é que, se você simplificar suas rotas, a navegação entre rotas se torna muito mais simples e se comporta como esperado / desejado sem o uso de
$router.replace
.Entendo que isso não resolve a questão da maneira que você está perguntando. Mas eu sugiro repensar essa rota de carregamento.
Aplicativo
Concha
Página principal
Página de resultados
Componente Resultados
Basicamente, exatamente o mesmo componente de resultados que você já possui, mas se
loading
for verdadeiro ouresults
nulo, como preferir, você pode criar um conjunto de dados falso para iterar e criar versões de esqueleto, se desejar. Caso contrário, você pode simplesmente manter as coisas do jeito que está.fonte
Outra opção é usar a API do histórico .
Quando estiver na tela Resultados, você poderá utilizar o ReplaceState para substituir o URL no histórico do navegador.
fonte
Isso pode ser feito com o
beforeEach
gancho do roteador.O que você precisa fazer é salvar uma variável globalmente ou em localStorage no
loading
componente quando os dados são carregados (antes de redirecionar para oresults
componente):E você deve verificar essa variável no gancho beforeEach e pular para o componente correto:
Além disso, lembre-se de redefinir o valor para false no seu
main
componente quando o botão de consulta for clicado (antes de rotear para oloading
componente):fonte
Sua tela de carregamento não deve ser controlada pelo vue-router. A melhor opção é usar uma sobreposição / modal para sua tela de carregamento, controlada por javascript. Existem muitos exemplos para o vue. Se você não consegue encontrar nada, o vue-bootstrap tem alguns exemplos fáceis de implementar.
fonte