Reputation: 6372
I have a <router-link />
that I want to use to navigate to another page in a Vue 3 application, but I also want to run another function when this link is clicked.
Right now I have to use an extra <span />
element to wrap the <router-link />
and add the @click
attribute there to rely on event bubbling. Adding the @click
handler on <router-link />
causes the router link not to work and the browser thinks it is just a normal anchor href.
<span @click="handleClose(imageId)">
<router-link
:to="{name: 'image', params: {'imageId': imageId}}"
class="permalink">
Permalink
</router-link>
</span>
Is there a better way?
Upvotes: 5
Views: 7554
Reputation: 2049
To avoid potential weird concurrency bugs (the view change could happen before your method being called, method which would then be attached to an unmounted component), I would do a programmatic navigation in your method:
<template>
<button type="button" @click="handleClose(imageId)">
Permalink
</button>
</template>
<script>
import router from '@/wherever/your/router/is/initialized';
export default {
methods: {
handleClose(imageId) {
// Do your stuff
router.push({ name: 'image', params: {'imageId': imageId}});
}
}
}
</script>
Upvotes: 5
Reputation: 14259
You must use the .native
modifier on the @click
event of router-link
. The reason is quite simple - router-link
is a Vue component but it does not emit a click
event. Therefore you have to listen for the native click
event coming from the browser.
https://github.com/vuejs/vue-router/issues/800
var router = new VueRouter({
routes:
[
{path: '/', component: {
template: '#first',
methods:
{
showAlert(text)
{
window.alert(text);
}
}
}},
{path: '/second', component: {
template: '#second',
methods:
{
showAlert(text)
{
window.alert(text);
}
}
}},
]
});
new Vue(
{
template: '#main',
router: router,
}).$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app">test</div>
<template id="main">
<div>
<router-view></router-view>
</div>
</template>
<template id="first">
<router-link to="/second" @click.native="showAlert('second')">GOTO second</router-link>
</template>
<template id="second">
<router-link to="/" @click.native="showAlert('first')">GOTO first</router-link>
</template>
Upvotes: 4