I want do create some some different ponents by looping through an array of ponents like in my example. But I want to create different event handlers for each ponent. How can I define them in my ponentData Array and bind them while looping?
ponentData: [
{ name: TestPane, props: { data: "hello" }, id: 1 },
{ name: TestPane, props: { data: "bye" }, id: 2 },
],
]
<div v-for="ponent in ponentData" :key="ponent.id">
<ponent v-bind:is="ponent.name" v-bind="ponent.props">
</ponent>
</div>
I want do create some some different ponents by looping through an array of ponents like in my example. But I want to create different event handlers for each ponent. How can I define them in my ponentData Array and bind them while looping?
ponentData: [
{ name: TestPane, props: { data: "hello" }, id: 1 },
{ name: TestPane, props: { data: "bye" }, id: 2 },
],
]
<div v-for="ponent in ponentData" :key="ponent.id">
<ponent v-bind:is="ponent.name" v-bind="ponent.props">
</ponent>
</div>
Share
Improve this question
asked Nov 13, 2020 at 12:17
Kevin W.Kevin W.
1011 silver badge9 bronze badges
3
- where are the handlers (methods) defined? – Boussadjra Brahim Commented Nov 13, 2020 at 12:19
- In the method section. I want to do something like: { name: TestPane, props: { data: "hello" }, id: 1 , @click: doSomething()}, – Kevin W. Commented Nov 13, 2020 at 12:24
-
In
ponentData
children, make another property likeclickEvent
and pass whatever function you want. Then in the v-for loop, add an@click="ponent.clickEvent"
to trigger that function. Should be as simple as that. – Kalnode Commented Apr 9, 2024 at 21:25
2 Answers
Reset to default 13You can use the v-on
directive. Let's understand how Vue bind your event listeners to the ponent first:
When you add a @input
to a ponnet what you are actualy doing is v-on:input
. Did you notice the v-on
over there? This means that you are actually passing an 'object of listeners' to the ponent.
Why not pass all of them in one go?
<template>
<section>
<div v-for="ponent in ponentData" :key="ponent.id">
<ponent v-bind:is="ponent.name" v-bind="ponent.props" v-on="ponent.on">
</ponent>
</div>
</section>
</template>
<script>
export default {
data: () => ({
ponentData: [
{ name: TestPane, props: { data: "hello" }, id: 1, on: { input: (e) => { console.log(e) } } },
{ name: TestPane, props: { data: "bye" }, id: 2, on: { input: (e) => { console.log(e); } } },
],
})
}
</script>
As you could guess you can listen to the events now inside of on
object. You can add more if you would like as well:
{
name: TestPane,
props: { data: "hello" },
id: 1,
on: {
input: (e) => { console.log(e) },
hover: (e) => { console.log('This ponent was hovered') }
}
}
Add method names to your array like :
ponentData: [
{ name: TestPane, props: { data: "hello" }, id: 1, method:"method1" },
{ name: TestPane, props: { data: "bye" }, id: 2 ,method:"method2"},
],
in template :
<ponent ... @click.native="this[ponent.method]()">
or add another method called handler which runs the appropriate ponent method :
<ponent ... @click.native="handler(ponent.method)">
methods:{
handler(methodName){
this[methodName]();
}
...
}
if the events are emitted from ponents, you should add their names and bind them dynamically :
ponentData: [
{ name: TestPane, props: { data: "hello" }, id: 1,event:'refresh', method:"method1" },
{ name: TestPane, props: { data: "bye" }, id: 2 ,event:'input',method:"method2"},
],
<ponent ... @[ponent.event]="handler(ponent.method)">