@click.prevent is not working on properly on a NuxtLink

I’ve been playing with Nuxt (2.15.7) and for whatever reason @click.stop does not work properly in my application. Here’s a very simple component that I have that goes directly to the link rather than trapping the event and logging my statement.

<template>
  <figure>
    <figcaption>{{photo.description}}</figcaption>
    <NuxtLink :to="url" @click.stop="goToPhoto">
      <img :src="photo.images.medium">
    </NuxtLink>
  </figure>
</template>

<script>
  export default {
    props: {
      photo: Object,
    },
    methods: {
      goToPhoto() {
        console.log('go to photo')
      }
    },
    computed: {
      url() {
        return `/photos/${this.photo.id}`
      }
    }
  }
</script>

If I replace the NuxtLink with the following, it works:

<NuxtLink :to="url" event="" @click.native="goToPhoto(), event => event.preventDefault()">

Any idea as to what might be causing these events to slip through or how I can better debug this?

Thanks!

.stop is working just fine, you’re probably mixing it up with .prevent - they are two event modifiers that work diffenetly: stop is not the modifier you want in this scenario.

Stops will stop the event bubbling up the visual tree after the sender element has processed its event handlers.

Prevent will remove any existing default browser behaviours from the event handlers such as Form submits or Anchor navigations.

no, @click.prevent doesn’t work either. that’s what i started with, hence the name of the title, but then i tried .stop to go scorched earth… i accidentally copied my example after i made the change.

neither @click.prevent nor @click.stop are working.

Just to add a little more info. Adding @click.prevent to an <a> tag works. In the following block, the event is captured, my log line is emitted, and my browser does not navigate to the url.

<a :href="url" @click.prevent="goToPhoto">
  <img :src="photo.images.medium">
</a>

This next block does not capture the event. The link behaves normally and my browser navigates to the url.

<NuxtLink :to="url" @click.prevent="goToPhoto">
  <img :src="photo.images.medium">
</NuxtLink>

And finally, this block properly captures the event, logs my message, and my browser does not navigate to the url:

<NuxtLink :to="url" event="" @click.native="goToPhoto(), event => event.preventDefault()">
  <img :src="photo.images.medium">
</a>

I’m running Nuxt 2.15.8 which appears to be running Vue 2.6.14.

And just to make sure that I didn’t accidentally introduce something along the way, I even reverted back to the initial commit that I ran after create-nuxt-app, added some test links similar to above, and saw the same behavior. So strange.

Reason why @click does not work is because it is an event handler on custom component. Event handlers on custom components can handle only events emitted by component using $emit() call.

<NuxtLink> (which just extends <RouterLink> from Vue Router) does NOT emit such event on click so that’s why your handler is not called.

Also almost all event modifiers (except once) works ONLY with native DOM events. Using them on custom component does nothing…

@click.native works because it tell Vue to place native event handler to a root element of that component (<a> in this case)

2 Likes

That makes sense. I guess the documentation that used @click event handlers in their examples led me in the wrong direction…

Just revisiting this to add a solution that could fit other situations. You can combine native and prevent to allow your attached root element event handler to get the prevent functionality you’re wanting to achieve.

<NuxtLink :to=“url” @click.native.prevent=“goToPhoto”>