Vue Router: Recursos Avançados

Passagem de Props para Componentes de Rota

Desacoplando com props:

const DetalhesUsuario = {
  props: ['identificador'],
  template: '<div>Detalhes do usuário {{ identificador }}</div>'
}
const roteador = new VueRouter({
  rotas: [
    { caminho: '/usuario/:identificador', componente: DetalhesUsuario, props: true },
    {
      caminho: '/usuario/:identificador',
      componentes: { padrao: DetalhesUsuario, barraLateral: BarraLateral },
      props: { padrao: true, barraLateral: false }
    }
  ]
})

Modo booleano: Quando props é definido como true, os parâmetros da rota são passados como atributos do componente.

Modo objeto:

const roteador = new VueRouter({
  rotas: [
    { caminho: '/promocao-da-campanha', componente: Promocao, props: { exibirPopup: false } }
  ]
})

Modo função: Para a rota /buscar?q=vue, a query é passada como propriedade para o componente.

const roteador = new VueRouter({
  rotas: [
    { caminho: '/buscar', componente: ResultadoBusca, props: (rota) => ({ termo: rota.query.q }) }
  ]
})

Modo Histórico

O Vue Router utiliza o modo hash por padrão. Para ativar o modo histórico:

const roteador = new VueRouter({
  modo: 'historico',
  rotas: [...]
})

Neste modo, as URLs são semelhantes a URLs convencionais, como http://meusite.com/perfil/id. É necessário configurar o servidor para redirecionar todas as solicitações para o index.html. Uma página 404 deve ser definida para rotas inexistentes.

const roteador = new VueRouter({
  modo: 'historico',
  rotas: [
    { caminho: '*', componente: PaginaNaoEncontrada }
  ]
})

Guardas de Navegação

Guarda global anterior:

const roteador = new VueRouter({ ... })

roteador.beforeEach((para, de, proximo) => {
  // Lógica de verificação
})

Parâmetros: 'para' é a rota de destino, 'de' é a rota de origem, e 'proximo' é uma função para controlar o fluxo.

Exemplo de verificação de autenticação:

roteador.beforeEach((para, de, proximo) => {
  if (para.nome !== 'tela-login') {
    if (usuarioAutenticado) proximo()
    else proximo({ nome: 'tela-login' })
  } else {
    if (usuarioAutenticado) proximo({ nome: 'painel' })
    else proximo()
  }
})

Hook global posterior:

roteador.afterEach((para, de) => {
  // Ações após a navegação, como carregamento de página
})

Guarda específica da rota:

const roteador = new VueRouter({
  rotas: [
    {
      caminho: '/configuracoes',
      componente: Configuracoes,
      antesDeEntrar: (para, de, proximo) => {
        // Verificação específica para esta rota
      }
    }
  ]
})

Guardas dantro do componente:

const PainelControle = {
  template: `...`,
  antesDaRotaEntrar (para, de, proximo) {
    // Chamado antes da confirmação da rota; não é possível acessar 'this'
  },
  antesDaRotaAtualizar (para, de, proximo) {
    // Chamado quando a rota muda, mas o componente é reutilizado
  },
  antesDaRotaSair (para, de, proximo) {
    // Chamado ao sair da rota; 'this' está disponível
  }
}

Metadados da Rota

Definir metadados na configuração da rota:

const roteador = new VueRouter({
  rotas: [
    {
      caminho: '/dashboard',
      componente: Dashboard,
      filhos: [
        {
          caminho: 'relatorio',
          componente: Relatorio,
          meta: { requerPermissao: true }
        }
      ]
    }
  ]
})

Acessar metadados nos guardas de navegação:

roteador.beforeEach((para, de, proximo) => {
  const permissaoNecessaria = para.meta.requerPermissao
  if (permissaoNecessaria) {
    if (temPermissao) proximo()
    else proximo({ nome: 'acesso-negado' })
  } else {
    proximo()
  }
})

Efeitos de Transição

Aplicar transições ao visualizador de rotas:

<transicao>
  <roteador-visualizacao></roteador-visualizacao>
</transicao>

Transições individuais por componente:

const SecaoInicial = {
  template: `
    <transicao nome="deslizar">
      <div class="secao-inicial">...</div>
    </transicao>
  `
}
const SecaoSecundaria = {
  template: `
    <transicao nome="esmaecer">
      <div class="secao-secundaria">...</div>
    </transicao>
  `
}

Obtenção de Dados

Obter dados após a conclusão da navegação:

<template>
  <div class="artigo">
    <div class="carregando" v-if="carregando">
      Carregando...
    </div>
    <div v-if="erro" class="erro">
      {{ erro }}
    </div>
    <div v-if="conteudo" class="conteudo">
      <h2>{{ conteudo.titulo }}</h2>
      <p>{{ conteudo.corpo }}</p>
    </div>
  </div>
</template>
export default {
  dados () {
    return {
      carregando: false,
      conteudo: null,
      erro: null
    }
  },
  criado () {
    this.carregarDados()
  },
  observar: {
    '$rota': 'carregarDados'
  },
  metodos: {
    carregarDados () {
      this.erro = this.conteudo = null
      this.carregando = true
      obterArtigo(this.$rota.params.id, (err, artigo) => {
        this.carregando = false
        if (err) {
          this.erro = err.toString()
        } else {
          this.conteudo = artigo
        }
      })
    }
  }
}

Obter dados antes da navegação com antesDaRotaEntrar:

export default {
  dados () {
    return {
      conteudo: null,
      erro: null
    }
  },
  antesDaRotaEntrar (para, de, proximo) {
    obterArtigo(para.params.id, (err, artigo) => {
      proximo(vm => vm.definirDados(err, artigo))
    })
  },
  antesDaRotaAtualizar (para, de, proximo) {
    this.conteudo = null
    obterArtigo(para.params.id, (err, artigo) => {
      this.definirDados(err, artigo)
      proximo()
    })
  },
  metodos: {
    definirDados (err, artigo) {
      if (err) {
        this.erro = err.toString()
      } else {
        this.conteudo = artigo
      }
    }
  }
}

Comportamento de Rolagem

Configuarr o comportamento de rolagem ao navegar entre rotas:

const roteador = new VueRouter({
  rotas: [...],
  comportamentoRolagem (para, de, posicaoSalva) {
    // Retornar a posição desejada para a rolagem
  }
})

Exemplo: rolar para o topo ao mudar de rota:

comportamentoRolagem (para, de, posicaoSalva) {
  return { x: 0, y: 0 }
}

Carregamento Preguiçoso de Rotas

Implementar carregamento assíncrono de componentes:

const ModuloFinanceiro = () => import('./ModuloFinanceiro.vue')
const roteador = new VueRouter({
  rotas: [
    { caminho: '/financeiro', componente: ModuloFinanceiro }
  ]
})

Tags: Vue Router Vue.js Guardas de Navegação Meta de Rota Carregamento Preguiçoso

Publicado em 6-28 10:40