O vue-router pode abrir um link em uma nova guia?

100

Eu tenho uma página de resumo e uma subpágina de detalhes. Todas as rotas são implementadas com vue-router(v 0.7.x) usando navegação programática como esta:

this.$router.go({ path: "/link/to/page" })

No entanto, quando eu faço o roteamento da página de resumo para a subpágina, preciso abrir a subpágina em uma nova guia, exatamente como faria ao adicionar _target="blank"a uma <a>tag.

Existe uma maneira de fazer isso?

Tang Jiong
fonte
4
Eu não acho que isso seja possível com o roteador vue, você pode extrair e construir seu url e usar window.open (url, '_blank')
Deepak
1
Sim, eles oficialmente dizem que é impossível. Obrigado.
Tang Jiong
há uma resposta abaixo que funciona, você deve aceitá-la como resposta à sua pergunta, não acha?
Andres Felipe

Respostas:

179

Acho que você pode fazer algo assim:

let routeData = this.$router.resolve({name: 'routeName', query: {data: "someData"}});
window.open(routeData.href, '_blank');

funcionou para mim. obrigado.

Rafael Andrs Cspedes Basterio
fonte
4
Esta parece ser a melhor maneira para mim. Você ainda usa $ router para construir o url sem ter que misturar algumas strings hackeadas, então usa window para abrir a nova aba. +1
John Smith
2
Esta é a solução mais completa, se o url da rota que você está tentando acessar mudar desta forma o mantém sob controle. bom!
Nitzankin
3
Infelizmente, este método é bloqueado por algum bloqueador de pop-up do navegador padrão
Photonic de
Esta é a melhor resposta IMO
kaleazy
1
@Rafel, posso pedir que você dê uma olhada em uma questão Vue.JS relacionada com o código-fonte no github do livro 'Full-Stack Vue.js 2 e Laravel 5' por Anthone Gore aqui stackoverflow.com/questions/59245577 /… ? Particularmente, dê uma olhada na seção EDIT: do OP?
Istiaque Ahmed
128

Parece que agora isso é possível em versões mais recentes (Vue Router 3.0.1):

<router-link :to="{ name: 'fooRoute'}" target="_blank">
  Link Text
</router-link>
Andrew Mao
fonte
Não parece que você pode passar parâmetros? basta abrir o próprio link. Corrigir?
Começou
@Gotts você também pode passar params e queryparams. O código para fazer isso é fornecido abaixo de <router-link: to = "{name: 'fooRoute', params: {param_var: 'id_parameter'}, query: {query_var: 'query_params'}}" target = "_ blank" > Texto do link </router-link>
Pushkar Shirodkar
Observe que isso é para o <router-link>, ele não funciona programaticamente com this.$router.push().
jplindstrom
22

Para aqueles que estão se perguntando, a resposta é não. Veja o problema relacionado no github.

P: O roteador vue pode abrir o link em uma nova guia de maneira programática

R: Não. Use um link normal.

wanyama_man
fonte
12
Obrigado, na verdade o problema é aberto por mim.
Tang Jiong
5
Agora é possível adicionar target="_blank"a uma <router-link>tag na v3 stackoverflow.com/a/49654382/2678454
obrigado
Achei isso muito útil em vez de construir o URL completo e usar window.open
Sainath SR
15

Caso você defina sua rota como a feita na pergunta (caminho: '/ link / para / página'):

import Vue from 'vue'
import Router from 'vue-router'
import MyComponent from '@/components/MyComponent.vue';

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/link/to/page',
      component: MyComponent
    }
  ]
})

Você pode resolver o URL em sua página de resumo e abrir sua subpágina conforme abaixo:

<script>
export default {
  methods: {
    popup() {
      let route = this.$router.resolve({path: '/link/to/page'});
      // let route = this.$router.resolve('/link/to/page'); // This also works.
      window.open(route.href, '_blank');
    }
  }
};
</script>

Claro, se você deu um nome à sua rota, você pode resolver o URL pelo nome:

routes: [
  {
    path: '/link/to/page',
    component: MyComponent,
    name: 'subPage'
  }
]

...

let route = this.$router.resolve({name: 'subPage'});

Referências:

Yuci
fonte
13

Em algum lugar do seu projeto, normalmente main.js ou router.js

import Router from 'vue-router'

Router.prototype.open = function (routeObject) {
  const {href} = this.resolve(routeObject)
  window.open(href, '_blank')
}

Em seu componente:

<div @click="$router.open({name: 'User', params: {ID: 123}})">Open in new tab</div>
Alice Chan
fonte
Não votando contra, mas talvez seja bom para Vue3? Porque console / registro deste. $ Router.open retorna undefined para mim
Dexygen
Essa abordagem é desencorajada, pois muda o protótipo. Você não pode registrá-lo, porque não faz parte da especificação.
adi518
6

Isso funcionou para mim-

let routeData = this.$router.resolve(
{
  path: '/resources/c-m-communities', 
  query: {'dataParameter': 'parameterValue'}
});
window.open(routeData.href, '_blank');

Modifiquei a resposta @Rafael_Andrs_Cspedes_Basterio

Nasir Khan
fonte
5

Basta escrever este código em seu arquivo de roteamento:

{
  name: 'Google',
  path: '/google',
  beforeEnter() {                    
                window.open("http://www.google.com", 
                '_blank');
            }
}
Harish Shinde
fonte
4

Acho que a melhor maneira é simplesmente usar:

window.open("yourURL", '_blank');

🚀 * voa para longe *

Nada Le Coupanec
fonte
2
Não longe o suficiente
Dexygen
3

Se você estiver interessado apenas em caminhos relativos como: /dashboard, /aboutetc, Veja outras respostas.

Se você deseja abrir um caminho absoluto como: https://www.google.compara uma nova guia, você deve saber que o Vue Router NÃO foi feito para lidar com isso.

No entanto, eles parecem considerar isso como uma solicitação de recurso. # 1280 . Mas até que eles façam isso,



Aqui está um pequeno truque que você pode fazer para lidar com links externos com vue-roteador.

  • Vá para a configuração do roteador (provavelmente router.js) e adicione este código:
/* Vue Router is not meant to handle absolute urls. */
/* So whenever we want to deal with those, we can use this.$router.absUrl(url) */
Router.prototype.absUrl = function(url, newTab = true) {
  const link = document.createElement('a')
  link.href = url
  link.target = newTab ? '_blank' : ''
  if (newTab) link.rel = 'noopener noreferrer' // IMPORTANT to add this
  link.click()
}

Agora, sempre que lidamos com URLs absolutos, temos uma solução. Por exemplo, para abrir o Google em uma nova guia

this.$router.absUrl('https://www.google.com)

Lembre-se de que, sempre que abrirmos outra página em uma nova guia, DEVEMOS usar noopener noreferrer.

Leia mais aqui

ou aqui

Roli Roli
fonte
funciona bem para mim em quase todos os dispositivos, exceto telefones celulares, onde a nova janela não abre!
javascript110899
0

Isso funciona para mim:

No modelo HTML: <a target="_blank" :href="url" @click.stop>your_name</a>

Em montado (): this.url = `${window.location.origin}/your_page_name`;

miko866
fonte
0

A maneira mais simples de fazer isso usando uma tag âncora seria esta:

<a :href="$router.resolve({name: 'posts.show', params: {post: post.id}}).href" target="_blank">
    Open Post in new tab
</a>
Scarwolf
fonte