182

I have a summary page and a detail subpage. All of the routes are implemented with vue-router (v 0.7.x) using programmatic navigation like this:

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

However, when I route from the summary page to the subpage, I need to open the subpage in a new tab just as one would by adding _target="blank" to an <a> tag.

Is there a way to do this?

thanksd
  • 54,176
  • 22
  • 157
  • 150
Tang Jiong
  • 1,893
  • 2
  • 11
  • 9
  • 6
    I dont think thats possible with vue router, you might extract and build your url and then use window.open(url, '_blank') – Deepak Oct 13 '16 at 12:22
  • 2
    Yes, they officially say it's impossible. Thank you. – Tang Jiong Oct 14 '16 at 02:08
  • there is an answer below that works, you should accept that as the response on your question, don't you think? – Andres Felipe Apr 04 '18 at 15:06
  • 1
    i go over all the answers and only thing i did was adding `target="_blank" ` to inside my router-link tag. but i am not sure if this is good practice or not. and I don't have any param – greenridinghood May 10 '21 at 17:36

13 Answers13

341

I think that you can do something like this:

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

It worked for me.

Update


For composition Api:

import { useRouter } from 'vue-router'
const router = useRouter();
const routeData = router.resolve({name: 'routeName', query: {data: "someData"}});
window.open(routeData.href, '_blank');
Kamran Allana
  • 543
  • 1
  • 6
  • 25
  • 4
    This seems like the best way to me. You still use $router to build the url without having to mash together some hacky string, then use window to open the new tab. +1 – John Smith Jan 27 '18 at 05:59
  • 4
    Unfortunately this method get block by some default browser popup blocker – Photonic Aug 17 '18 at 08:49
  • Note that location parameter uses `path` instead of `name` if you use `query`. – Jesús Fuentes Oct 16 '19 at 09:51
  • One problem with this is that window.open does not pass headers like tokens and others. – Marcus Dec 07 '19 at 14:52
  • 1
    @Rafel, May i ask you to have a look at a Vue.JS question related with the source code in github of the book 'Full-Stack Vue.js 2 and Laravel 5' by Anthone Gore here https://stackoverflow.com/questions/59245577/laravel-vuejs-router-view-does-not-render-the-component ? Particularly take a look at the EDIT: section of the OP ? – Istiaque Ahmed Dec 13 '19 at 12:04
  • Create a link instead, like `...` ; avoid using Javascript to open links for accessibility, SEO & security reasons. What's more a link will still work even if there're errors in your JS code that break your app. – Nico Prat Feb 20 '20 at 09:52
  • In addition... if you don't want to open a new tab that is already open. It's possible to configure the `target` with an id of the refereced value with some other identification. Like `window.open(routeData.href, 'details ' + id);` – Sham Fiorin Jan 13 '23 at 13:35
217

It seems like this is now possible in newer versions (Vue Router 3.0.1):

<router-link :to="{ name: 'fooRoute'}" target="_blank">
  Link Text
</router-link>
Andrew Mao
  • 35,740
  • 23
  • 143
  • 224
25

For those who are wondering the answer is no. See related issue on github.

Q: Can vue-router open link in new tab progammaticaly

A: No. use a normal link.

wanyama_man
  • 476
  • 4
  • 5
21

In case that you define your route like the one asked in the question (path: '/link/to/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
    }
  ]
})

You can resolve the URL in your summary page and open your sub page as below:

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

Of course if you've given your route a name, you can resolve the URL by name:

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

...

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

References:

Yuci
  • 27,235
  • 10
  • 114
  • 113
13

Somewhere in your project, typically main.js or router.js

import Router from 'vue-router'

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

In your component:

<div @click="$router.open({name: 'User', params: {ID: 123}})">Open in new tab</div>
Alice Chan
  • 2,814
  • 2
  • 16
  • 16
  • Not down-voting, but maybe it's nice for Vue3? Because console/logging this.$router.open returns undefined for me – Dexygen Dec 06 '19 at 16:35
  • This approach is discouraged as it mutates prototype. You can't log it, because it isn't part of the spec. – adi518 Mar 16 '20 at 01:41
12

This worked for me-

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

I modified @Rafael_Andrs_Cspedes_Basterio answer

Nasir Khan
  • 753
  • 1
  • 9
  • 22
10

Just write this code in your routing file :

{
  name: 'Google',
  path: '/google',
  beforeEnter() {                    
                window.open("http://www.google.com", 
                '_blank');
            }
}
Harish Shinde
  • 141
  • 1
  • 11
8

I think the best way is to simply use:

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

* flies away *

6

If you are interested ONLY on relative paths like: /dashboard, /about etc, See other answers.

If you want to open an absolute path like: https://www.google.com to a new tab, you have to know that Vue Router is NOT meant to handle those.

However, they seems to consider that as a feature-request. #1280. But until they do that,



Here is a little trick you can do to handle external links with vue-router.

  • Go to the router configuration (probably router.js) and add this 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()
}

Now, whenever we deal with absolute URLs we have a solution. For example to open google to a new tab

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

Remember that whenever we open another page to a new tab we MUST use noopener noreferrer.

Read more here

or Here

Roland
  • 24,554
  • 4
  • 99
  • 97
3

The simplest way of doing this using an anchor tag would be this:

<a :href="$router.resolve({name: 'posts.show', params: {post: post.id}}).href" target="_blank">
    Open Post in new tab
</a>
xTheWolf
  • 1,756
  • 4
  • 18
  • 43
1

Below code is to open a new tab with parameter.

With router link=

<router-link
                  :to="{ name: 'task_section',query: {reportId: item.task,}}"
                  target="_blank"> Link Text
              </router-link>

Now access to the sented data

this.$route.query.reportId
Mahadi Hassan
  • 149
  • 1
  • 8
1

It can be achieved by creating a separate method for window redirect like this.

const openLinkInNewTab = (url) => {
  window.open(url, '_blank');
}

then use it on template like this

<a href="javascript:void(0)" @click="openLinkInNewTab('https://devsbuddy.com')">
    Open in new tab
</a>
Shoaib Khan
  • 830
  • 1
  • 9
  • 17
0

This works for me:

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

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

miko866
  • 182
  • 2
  • 9