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>
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:
<button @click="$emit('enlarge-text')"> Enlarge text</button>
@ is the
Component handles native
click event and emits parent's
enlarge-text can be replaced with
click to make it look like we're handling a native click event:
<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>