8

I render Vue components using v-for:

<component
    v-for="component in components"
    :is="component.type"
    @click="myFunction(component.id)">
</component>

Clicking on the rendered component doesn't fire the myFunction method. However, clicking a manually inserted component does:

<div @click="myFunction('...')"></div>

How to correct this?

4 Answers 4

12

Add the .native modifier to listen for a native event instead of a component event.

<component
    v-for="component in components"
    :is="component.type"
    @click.native="myFunction(component.id)">
</component>

Source: https://v2.vuejs.org/v2/api/#v-on

Sign up to request clarification or add additional context in comments.

Comments

1

You can pass the click handler as a prop to the child component, for instance:

<component
   v-for="component in components"
   :is="component.type"
   :on-click="myFunction.bind(this, component.id)">
</component>

// Component
<template>
  <button @click="onClick">Click me</button>
</template>
<script>
  export default {
    props: ['onClick']
  }
</script>

Comments

0

Try following:

<template v-for="component in components">
  <component :is="component.type" @click="myFunction(component.id)" />
</template > 

3 Comments

The @click binding needs to be on the div but otherwise this works. Why is that? This creates unnecessary elements in the DOM.
@Mikko I have modified the answer, which should not add unnecessary elements in the DOM.
Binding the click event to the template tag doesn't work either.
0

I'm guessing that what you are trying to do is not needed or correct. If you want to call a function defined in the parent whenever the child component is clicked you can just wrap the component in an element and bind the event to that wrapper. That way the function will fire whenever you click whichever component is rendered inside it and you'll have not events bound directly to components

<div class="wrapper" v-for="component in components" @click="myFunction(component.id)">
    <component :is="component.type"/>
</div>

That should do it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.