Search code examples
vue.jsvue-routervuejs3vue-router4

on click method with vue-router 4


With vue-router 3, it was possible to add a method on router-link with @click.native="myMethod" like explained here.

In vue 3 the .native modifier was deprecated.

When a user clicks on <router-link to="somewhere" @click="myMethod">Click me</router-link>, it creates a bug where the entire app reloads.

With vue-router 4, what is the correct way to trigger a method on click on a router-link tag?


Solution

  • Make sure your vue-router version is at least 4.0.6 (run npm show vue-router or npm outdated). In that version, there's a fix that allows doing what you're trying to achieve. Basically, the piece of code in your question should just work now.

    So like:

    <template>
      <router-link to="/somePath" @click="myMethod()">Click me</router-link>
    </template>
    <script>
    export default {
      methods: {
        myMethod() {
          console.log('hello');
        }
      }
    }
    </script>
    

    Here's a runnable snippet with Vue 3 and the newest vue router 4

    const App = {
      template: `
        <div class="wrapper">
          <router-view />
          <router-link to="/hello" @click="myMethod()">Link (click me)</router-link>
          Did my method run: {{didMyMethodRun}}
        </div>
      `,
      data() {
        return {
          didMyMethodRun: false,
        }
      },
      methods: {
        myMethod() {
          this.didMyMethodRun = true
        }
      }
    }
    const router = VueRouter.createRouter({
      history: VueRouter.createWebHashHistory(),
      routes: [
        {path: '/', component: {template: 'You are now on default route'}},
        {path: '/hello', component: {template: 'You are now hello route'}},
      ]
    })
    const app = Vue.createApp(App);
    app.use(router)
    app.mount('#app');
    .wrapper {
      display: flex;
      flex-direction: column;
    }
    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://unpkg.com/vue-router@4"></script>
    <html>
     <body>
       <div id="app"/>
     </body>
    </html>

    Link to CHANGELOG