¿Puede vue-router abrir un enlace en una nueva pestaña?

97

Tengo una página de resumen y una subpágina de detalles. Todas las rutas se implementan con vue-router(v 0.7.x) usando navegación programática como esta:

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

Sin embargo, cuando me dirijo desde la página de resumen a la subpágina, necesito abrir la subpágina en una nueva pestaña tal como lo haría al agregar _target="blank"una <a>etiqueta.

¿Hay alguna forma de hacer esto?

Tang Jiong
fuente
3
No creo que eso sea posible con el enrutador vue, puede extraer y construir su URL y luego usar window.open (url, '_blank')
Deepak
1
Sí, oficialmente dicen que es imposible. Gracias.
Tang Jiong
hay una respuesta a continuación que funciona, debería aceptarla como respuesta a su pregunta, ¿no cree?
Andrés Felipe

Respuestas:

170

Creo que puedes hacer algo como esto:

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

funcionó para mí. Gracias.

Rafael Andrs Cspedes Basterio
fuente
4
Esta me parece la mejor manera. Aún usas $ router para construir la URL sin tener que mezclar alguna cadena pirata, luego usa window para abrir la nueva pestaña. +1
John Smith
2
Esta es la solución más completa, si la URL de la ruta a la que intentas acceder cambia de esta manera te mantiene bajo control. ¡bonito!
Nitzankin
3
Desafortunadamente, este método es bloqueado por algún bloqueador de ventanas emergentes del navegador predeterminado
Photonic
Esta es la mejor respuesta en mi opinión
kaleazy
1
@Rafel, ¿puedo pedirle que eche un vistazo a una pregunta de Vue.JS relacionada con el código fuente en github del libro 'Full-Stack Vue.js 2 y Laravel 5' de Anthone Gore aquí stackoverflow.com/questions/59245577 /… ? En particular, eche un vistazo a la sección EDITAR: ¿del OP?
Istiaque Ahmed
124

Parece que esto ahora es posible en versiones más recientes (Vue Router 3.0.1):

<router-link :to="{ name: 'fooRoute'}" target="_blank">
  Link Text
</router-link>
Andrew Mao
fuente
Sin embargo, ¿no parece que puedas pasar parámetros? simplemente abra el enlace. ¿Correcto?
Gotts
@Gotts también puede pasar params y queryparams. El código para hacer eso se proporciona a continuación <router-link: to = "{nombre: 'fooRoute', params: {param_var: 'id_parameter'}, consulta: {query_var: 'query_params'}}" target = "_ blank" > Texto del enlace </router-link>
Pushkar Shirodkar
Tenga en cuenta que esto es para <router-link>, no funciona programáticamente con this.$router.push().
jplindstrom
22

Para aquellos que se preguntan, la respuesta es no. Consulte el problema relacionado en github.

P: ¿Puede vue-router abrir el enlace en una nueva pestaña de forma programada?

R: No. use un enlace normal.

wanyama_man
fuente
12
Gracias, de hecho, yo abro el tema.
Tang Jiong
5
Ahora es posible agregar target="_blank"a una <router-link>etiqueta en v3 stackoverflow.com/a/49654382/2678454
gracias el
Encontré esto muy útil en lugar de construir la URL completa y usar window.open
Sainath SR
14

En caso de que defina su ruta como la que se hizo en la pregunta (ruta: '/ enlace / a / 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
    }
  ]
})

Puede resolver la URL en su página de resumen y abrir su subpágina de la siguiente manera:

<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>

Por supuesto, si le ha dado un nombre a su ruta, puede resolver la URL por nombre:

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

...

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

Referencias:

Yuci
fuente
11

En algún lugar de su proyecto, normalmente main.js o router.js

import Router from 'vue-router'

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

En su componente:

<div @click="$router.open({name: 'User', params: {ID: 123}})">Open in new tab</div>
Alice Chan
fuente
No votar negativamente, pero ¿tal vez sea bueno para Vue3? Porque la consola / registro de este. $ Router.open devuelve indefinido para mí
Dexygen
Este enfoque se desaconseja ya que muta el prototipo. No puede registrarlo porque no forma parte de la especificación.
adi518
4

Creo que la mejor manera es simplemente usar:

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

🚀 * se va volando *

Nada Le Coupanec
fuente
2
No lo suficientemente lejos
Dexygen
4

Simplemente escriba este código en su archivo de enrutamiento:

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

Esto funcionó para mí

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

Modifiqué la respuesta de @Rafael_Andrs_Cspedes_Basterio

Nasir Khan
fuente
3

Si usted está interesado sólo en las trayectorias relativas como: /dashboard, /aboutetc, Ver otras respuestas.

Si desea abrir una ruta absoluta como: https://www.google.coma una nueva pestaña, debe saber que Vue Router NO está destinado a manejarlos.

Sin embargo, parecen considerar eso como una solicitud de función. # 1280 . Pero hasta que hagan eso,



Aquí hay un pequeño truco que puede hacer para manejar enlaces externos con vue-router.

  • Vaya a la configuración del enrutador (probablemente router.js) y agregue 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()
}

Ahora, siempre que tratemos con URL absolutas, tenemos una solución. Por ejemplo, para abrir Google en una nueva pestaña.

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

Recuerde que cada vez que abrimos otra página a una nueva pestaña DEBEMOS usar noopener noreferrer.

Leer más aquí

o aquí

roli roli
fuente
funciona bien para mí en casi todos los dispositivos, excepto en teléfonos móviles, donde la nueva ventana no se abre.
javascript110899
0

Esto funciona para mi:

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

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

miko866
fuente
0

La forma más sencilla de hacer esto usando una etiqueta de anclaje sería la siguiente:

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