Vue v-on:click does not work on component Vue v-on:click does not work on component vue.js vue.js

Vue v-on:click does not work on component

If you want to listen to a native event on the root element of a component, you have to use the .native modifier for v-on, like following:

<template>  <div id="app">    <test v-on:click.native="testFunction"></test>  </div></template>

or in shorthand, as suggested in comment, you can as well do:

<template>  <div id="app">    <test @click.native="testFunction"></test>  </div></template>

Reference to read more about native event

I think the $emit function works better for what I think you're asking for. It keeps your component separated from the Vue instance so that it is reusable in many contexts.

// Child component<template>  <div id="app">    <test @click="$emit('test-click')"></test>  </div></template>

Use it in HTML

// Parent component<test @test-click="testFunction">

It's the @Neps' answer but with details.

Note: @Saurabh's answer is more suitable if you don't want to modify your component or don't have access to it.

Why can't @click just work?

Components are complicated. One component can be a small fancy button wrapper, and another one can be an entire table with bunch of logic inside. Vue doesn't know what exactly you expect when bind v-model or use v-on so all of that should be processed by component's creator.

How to handle click event

According to Vue docs, $emit passes events to parent. Example from docs:

Main file

<blog-post  @enlarge-text="onEnlargeText"/>


<button @click="$emit('enlarge-text')">  Enlarge text</button>

(@ is the v-on shorthand)

Component handles native click event and emits parent's @enlarge-text="..."

enlarge-text can be replaced with click to make it look like we're handling a native click event:

<blog-post  @click="onEnlargeText"></blog-post>
<button @click="$emit('click')">  Enlarge text</button>

But that's not all. $emit allows to pass a specific value with an event. In the case of native click, the value is MouseEvent (JS event that has nothing to do with Vue).

Vue stores that event in a $event variable. So, it'd the best to emit $event with an event to create the impression of native event usage:

<button v-on:click="$emit('click', $event)">  Enlarge text</button>