Enclosing a router-link tag in a button in vuejs
Solution 1
You can use tag
prop.
<router-link to="/foo" tag="button">foo</router-link>
Please use v-slot if you use 3.0+ (thanks to Romain and Jeff)
Solution 2
While the answers on here are all good, none seem to be the simplest solution. After some quick research, it seems that the real easiest way to make a button use vue-router is with the router.push
call. This can be used within a .vue template like this:
<button @click="$router.push('about')">Click to Navigate</button>
Super simple and clean. I hope someone else finds this useful!
Source: https://router.vuejs.org/guide/essentials/navigation.html
Solution 3
@choasia's answer is correct.
Alternatively, you could wrap a button
tag in a router-link
tag like so:
<router-link :to="{name: 'myRoute'}">
<button id="myButton" class="foo bar">Go!</button>
</router-link>
This is not so clean because your button will be inside a link element (<a>
). However, the advantage is that you have a full control on your button, which may be necessary if you work with a front-end framework like Bootstrap.
I have never used this technique on buttons, to be honest. But I did this on divs quite often...
Solution 4
Official Answer as of 2022
Use the slots api Documentation Here
Example using the slots api
<router-link
to="/about"
v-slot="{href, route, navigate}"
>
<button :href="href" @click="navigate" class='whatever-you-want'>
{{ route.name }}
</button>
</router-link>
If you think this is unintuitive/verbose, please complain over here
Why are the other answers problematic?
-
@choasia's answer (using the tag prop) is deprecated and doesn't allow for props to be passed to the component
-
@Badacadabra's answer causes problems with CSS especially if the button is from a library (ex: adding a margin, or positioning)
Solution 5
Thanks to Wes Winder's answer, and extending it to include route params:
<button @click="$router.push({name: 'about-something', params: { id: 'abc123' },})">Click to Navigate</button>
And reiterating the source which Wes provided: https://router.vuejs.org/guide/essentials/navigation.html
Kushagra Agarwal
Updated on July 08, 2022Comments
-
Kushagra Agarwal almost 2 years
Can I wrap or enclose a
router-link
tag in abutton
tag?When I press the button, I want it to route me to the desired page.
-
vir us about 5 yearsAdditionally one can specify tag="span" inside <router-link> so it doesn't apply <a> styles which gives even better control on the looks: <router-link to="/foo" tag="span"> <Button> Button Text </Button> </router-link>
-
Joe Who about 5 yearsYes thank you! This was the simplest, and worked perfectly. And I could style my button however I chose. If you need to use params, you can also do something like this: <button @click="$router.push({name: 'about', params: { id: $route.params.id },})">Click to Navigate</button>
-
andcl almost 5 yearsWhat if that button accepts some props? How to pass them out?
-
Tozz almost 5 yearsBut the words in button (e.g. "Go!" in your example) will have the blue underline, which is not beautiful...
-
Ciabaros over 4 yearsEven with frameworks like Bootstrap, this is hardly ever necessary, because you can include standard attributes like class right in the router-link tag, and these will be applied to the rendered element, even a button, when you use tag="button": <router-link tag="button" class="btn btn-primary" to="..."></router-link>
-
Jeff Hykin over 4 years@andcl I had the same question, I posted the answer below, which was told to me by the Vue-Router team on GitHub here: github.com/vuejs/vue-router/issues/3003
-
Akin Hwan over 4 yearsi tried to upvote this almost a year after i already did! akkk thanks again
-
sshow over 4 yearsIf you're not on version >= 3.1.0, the item in the slot will silently be ignored without any errors show. Link to docs: router.vuejs.org/api/#v-slot-api-3-1-0
-
The Fool over 3 yearsi cannot download 3.1.0 it says the latest is 3.0.0 rc
-
Anuga over 3 yearsIt's not Vue 3.1.0, it's vue-router 3.1.0.
-
Jeff Hykin over 3 yearsThanks @Anuga, fixed it 👍 And thanks @ sshow, documentation is linked now.
-
Tomas Chabada almost 3 yearsThe best answer for me
-
Nikita over 2 yearsNote that this answer this won't allow to use browser supported features such as press Ctrl+Click to open link in new tab or preview of link in bottom-left corner of browser window.
-
Steven Spungin over 2 yearsUse the modern slot API
<template #default="{href,route,navigate}">
-
Jeff Hykin over 2 years@Steven could you link the documentation on that? I haven't seen it yet but that looks interesting
-
Steven Spungin over 2 years
-
Jeff Hykin over 2 yearsHmm I'm not totally sure how that would apply to the example. Are you saying to replace
v-slot="{href, route, navigate}"
with#default="{href, route, navigate}"
? It looks like v-slots is shorter, still valid, and backwards compatible with Vue 2 -
Charles HETIER about 2 yearsThe
:href
should not be bound on the button. The targeted url is already held by the propertyto="xxx"
of the<router-link>
-
Romain Vincent about 2 yearsBut "tag" is no longer supported by vue-router. See official migration note. And anyway, I don't recall exactly, but I doubt it handled additional link features and accessibility.