Evgeniy Miroshnichenko
Evgeniy Miroshnichenko

Reputation: 1865

Add event listener to <router-link> component using "v-on:" directive - VueJS

I'm attempting to add a custom handler InlineButtonClickHandler to a <router-link> component's click event, so that I can emit a custom appSidebarInlineButtonClick event.

But, my code isn't working. What am I doing wrong?

<template>
   <router-link :to="to" @click="InlineButtonClickHandler">
     {{ name }}
   </router-link>
</template>

<script type="text/babel">
export default {
  props: {
    to: { type: Object, required: true },
    name: { type: String, required: true }
  },
  methods: {
    InlineButtonClickHandler(event) {
      this.$emit('appSidebarInlineButtonClick');
    }
  }
} 
</script>

Upvotes: 70

Views: 78903

Answers (4)

Jan Verhulst
Jan Verhulst

Reputation: 46

What I ended up doing is creating a wrapper component for the router link which emits the native click event as a regular click and then use that component instead:

<template>
  <router-link v-bind="$attrs" v-on="$listeners" @click.native="onClick">
    <slot />
  </router-link>
</template>

<script>
export default {
  name: 'RouterLinkWithClickEvent',
  methods: {
    onClick(...args) {
      this.$emit('click', ...args);
    }
  }
};
</script>

Upvotes: 1

thanksd
thanksd

Reputation: 55644

You need to add the .native modifier:

<router-link
    :to="to"
    @click.native="InlineButtonClickHandler"
>
    {{name}}
</router-link>

This will listen to the native click event of the root element of the router-link component.

Upvotes: 158

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

With vue 3 and vue router 4 the @event and tag prop are removed according to this and instead of that you could use v-slot:

const Home = {
  template: '<div>Home</div>'
}
const About = {
  template: '<div>About</div>'
}
let routes = [{
  path: '/',
  component: Home
}, {
  path: '/about',
  component: About
}, ]

const router = VueRouter.createRouter({
  history: VueRouter.createWebHashHistory(),
  routes,
})


const app = Vue.createApp({
  methods: {
    test() {
      console.log("test")
    }
  }
})

app.use(router)

app.mount('#app')
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-router@4"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>

    <router-link to="/" v-slot="{navigate}">
      <span @click="test" role="link">Go to Home</span>
    </router-link>
    <br/>
    <router-link to="/about">Go to About</router-link>
  </p>

  <router-view></router-view>
</div>

Upvotes: 4

许浩东
许浩东

Reputation: 119

<router-link:to="to">
    <span @click="InlineButtonClickHandler">{{name}}</span>
</router-link>

Maybe you can try this.

Upvotes: 11

Related Questions