Vue-router peut-il ouvrir un lien dans un nouvel onglet?


97

J'ai une page de résumé et une sous-page de détails. Toutes les routes sont implémentées avec vue-router(v 0.7.x) en utilisant la navigation programmatique comme ceci:

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

Cependant, lorsque je passe de la page de résumé à la sous-page, je dois ouvrir la sous-page dans un nouvel onglet comme on le ferait en l'ajoutant _target="blank"à une <a>balise.

Y a-t-il un moyen de faire cela?


3
Je ne pense pas que ce soit possible avec le routeur vue, vous pouvez extraire et construire votre URL, puis utiliser window.open (url, '_blank')
Deepak

1
Oui, ils disent officiellement que c'est impossible. Merci.
Tang Jiong

il y a une réponse ci-dessous qui fonctionne, vous devriez l'accepter comme réponse à votre question, vous ne pensez pas?
Andres Felipe

Réponses:


169

Je pense que vous pouvez faire quelque chose comme ça:

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

cela a fonctionné pour moi. Merci.


4
Cela me semble être le meilleur moyen. Vous utilisez toujours $ router pour créer l'url sans avoir à écraser une chaîne hacky, puis utilisez window pour ouvrir le nouvel onglet. +1
John Smith

2
C'est la solution la plus complète, si l'URL de l'itinéraire auquel vous essayez d'accéder change de cette façon vous permet de rester en échec. agréable!
Nitzankin le

3
Malheureusement, cette méthode est bloquée par un bloqueur de popup de navigateur par défaut
Photonic

C'est la meilleure réponse IMO
kaleazy

1
@Rafel, puis-je vous demander de jeter un œil à une question de Vue.JS liée au code source dans github du livre 'Full-Stack Vue.js 2 and Laravel 5' par Anthone Gore ici stackoverflow.com/questions/59245577 /… ? Jetez un œil en particulier à la section EDIT: du PO?
Istiaque Ahmed

123

Il semble que cela soit désormais possible dans les versions plus récentes (Vue Router 3.0.1):

<router-link :to="{ name: 'fooRoute'}" target="_blank">
  Link Text
</router-link>

Ne semble-t-il pas que vous puissiez passer des paramètres? ouvrez simplement le lien lui-même. Correct?
Gotts

@Gotts vous pouvez également transmettre des paramètres et des requêtes. Le code pour faire cela est donné ci-dessous <router-link: to = "{name: 'fooRoute', params: {param_var: 'id_parameter'}, query: {query_var: 'query_params'}}" target = "_ blank" > Texte du lien </router-link>
Pushkar Shirodkar

Notez que c'est pour le <router-link>, cela ne fonctionne pas par programme avec this.$router.push().
jplindstrom

22

Pour ceux qui se demandent, la réponse est non. Voir le problème associé sur github.

Q: Peut vue-router ouvrir le lien dans un nouvel onglet de programmation

R: Non, utilisez un lien normal.


12
Merci, en fait le problème est ouvert par moi.
Tang Jiong

5
Maintenant possible d'ajouter target="_blank"à une <router-link>balise dans la v3 stackoverflow.com/a/49654382/2678454
merci le

J'ai trouvé cela très utile au lieu de construire l'URL complète et d'utiliser window.open
Sainath SR

14

Dans le cas où vous définissez votre itinéraire comme celui posé dans la question (chemin: '/ lien / vers / page'):

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
    }
  ]
})

Vous pouvez résoudre l'URL dans votre page de résumé et ouvrir votre sous-page comme ci-dessous:

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

Bien sûr, si vous avez donné un nom à votre itinéraire, vous pouvez résoudre l'URL par son nom:

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

...

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

Références:


11

Quelque part dans votre projet, généralement main.js ou router.js

import Router from 'vue-router'

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

Dans votre composant:

<div @click="$router.open({name: 'User', params: {ID: 123}})">Open in new tab</div>

Pas de vote négatif, mais peut-être que c'est bien pour Vue3? Parce que la console / la journalisation de ceci. $ Router.open renvoie undefined pour moi
Dexygen

Cette approche est déconseillée car elle mute le prototype. Vous ne pouvez pas le connecter, car il ne fait pas partie de la spécification.
adi518

4

Je pense que le meilleur moyen est simplement d'utiliser:

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

🚀 * s'envole *


2
Pas assez loin
Dexygen

4

Écrivez simplement ce code dans votre fichier de routage:

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

4

Cela a fonctionné pour moi-

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

J'ai modifié la réponse @Rafael_Andrs_Cspedes_Basterio


3

Si vous êtes intéressé uniquement sur des chemins relatifs comme: /dashboard, /aboutetc, Voir d' autres réponses.

Si vous voulez ouvrir un chemin absolu comme: https://www.google.comvers un nouvel onglet, vous devez savoir que Vue Router n'est PAS destiné à les gérer.

Cependant, ils semblent considérer cela comme une demande de fonctionnalité. # 1280 . Mais jusqu'à ce qu'ils fassent ça,



Voici une petite astuce que vous pouvez faire pour gérer les liens externes avec vue-router.

  • Accédez à la configuration du routeur (probablement router.js) et ajoutez ce code:
/* 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()
}

Désormais, chaque fois que nous traitons des URL absolues, nous avons une solution. Par exemple pour ouvrir google dans un nouvel onglet

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

N'oubliez pas que chaque fois que nous ouvrons une autre page vers un nouvel onglet, nous DEVONS utiliser noopener noreferrer.

En savoir plus ici

ou ici


fonctionne bien pour moi sur presque tous les appareils sauf les téléphones mobiles, où la nouvelle fenêtre ne s'ouvre pas!
javascript110899

0

Cela fonctionne pour moi:

Dans le modèle HTML: <a target="_blank" :href="url" @click.stop>your_name</a>

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


0

La façon la plus simple de faire cela en utilisant une balise d'ancrage serait la suivante:

<a :href="$router.resolve({name: 'posts.show', params: {post: post.id}}).href" target="_blank">
    Open Post in new tab
</a>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.