Enclosing a router-link tag in a button in vuejs
Buttonvue.jsVue RouterButton Problem Overview
Can I wrap or enclose a router-link
tag in a button
tag?
When I press the button, I want it to route me to the desired page.
Button Solutions
Solution 1 - Button
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 - Button
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 - Button
@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 - Button
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
Solution 5 - Button
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 6 - Button
Now days (VueJS >= 2.x) you would do:
<router-link tag="button" class="myClass" id="button" :to="place.to.go">Go!</router-link>
Solution 7 - Button
> Routing methods using method as well routing
-
Router link > >
<router-link to="/login">Login </router-link>
-
When click on button that type call another route.
> > >
<script>
export default {
name:'auth',
data() {
return {}
},
methods: {
onLogIn() {
this.$router.replace('/dashboard');
}
}
}
Solution 8 - Button
I'm working on Vue CLI 2 and this one has worked for me!
<router-link to="/about-creator">
<button>About Creator</button>
</router-link>
Solution 9 - Button
// literal string path
router.push('home')
// object
router.push({ path: 'home' })
// named route
router.push({ name: 'user', params: { userId: '123' } })
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })
Solution 10 - Button
Using the v-btn component you can simply:
<v-btn onclick="location.href='https://www.Google.com'" type="button" class="mb-4">Google</v-btn>
Solution 11 - Button
Sadly no, there is currently no way to do this properly.
I say properly because there obviously are several solutions that were already proposed to this question. The problem is: they seem to work but really they are not correct.
Here is why:
-
It is invalid to put any actionable element inside of another in html (there's plenty of invalid html out there and it has not caught fire yet, am I right?).
-
Most of the solutions I've seen here don't provide any navigation accessibility (nor link features such as "open link in new tab").
-
The one that does (by Jeff Hykin) has a couple of draw backs too:
- It fails to observe point 1)
- In his snippet,
@click="navigate"
is not necessary because<router-link>
is really an<a>
, which will trigger a navigation by itself andhref
is totally useless to a<button>
. - EDIT: Answer by Badacadabra is a bit better, but still point 1)
Assuming what you want is to reuse a properly styled button component to be used as a valid accessible link.
The real solution and you won't like it (I don't), is to create a component for the button, create another for the link and put whatever can be reused in yet another file (a base actionable component for example).
If the button comes from a library, well, another example that libraries never really solve every problem for you.
Solution 12 - Button
An example using bootstrap-vue and creating a link with the id inside a table row:
<b-table :fields="fields" :items="items">
<template v-slot:cell(action)="data">
<router-link :to="`/rounds/${data.item.id}`" v-slot="{ href, route, navigate}">
<b-button :href="href" @click="navigate" color="primary" style="text">{{ data.item.id }}</b-button>
</router-link>
</template>
</b-table>
Where fields
and items
are the columns names and the table content, respectively.