I have a component that i loop through using v-for and props. I want every rendered component to have a different on click event but i can't figure out how to pass a function as a prop.
Code:
Component:
<template>
<div v-on:click="cardProperties.scrollFunction" :id="cardProperties.id" >
<div >
<h2>{{cardProperties.title}}</h2>
<font-awesome-icon :icon="cardProperties.icon" />
<p>{{cardProperties.text}}</p>
</div>
</div>
</template>
<script>
export default {
name: 'card-container',
components: {
},
props: {
cardProperties: Object,
},
data() {
return{
cardProps: this.cardProperties
}
},
methods: {
musicScroll() {
const musicDiv = document.getElementById("music");
if(musicDiv != null){
musicDiv.scrollIntoView({behavior: 'smooth'})
}
},
maoScroll() {
const maoDiv = document.getElementById("mao");
if(maoDiv != null){
maoDiv.scrollIntoView({behavior: 'smooth'})
}
},
},
}
</script>
App.vue:
<card
v-for="cardProperties in cardPropsArray"
v-bind:key="cardProperties.text"
:cardProperties = cardProperties
/>
...
cardPropsArray:[
{
id: "music",
scrollFunction: "musicScroll()",
title: "Musik",
icon: "fa-solid fa-music",
text: "/play"
},
{
id: "mao",
scrollFunction: "maoScroll()",
title: "Med Andra Ord",
icon: "fa-solid fa-hourglass-end",
text: "/MAO"
},
I have tried to pass "scrollFunction" as a prop but since it sends the prop as a string it doesn't work. It results in the error message: "TypeError: $props.cardProperties.scrollFunction is not a function"
CodePudding user response:
You can make a function an object property by ommitting the quotes! With the quotes it is always a string:
{
id: "music",
scrollFunction: musicScroll,
title: "Musik",
icon: "fa-solid fa-music",
text: "/play"
}
CodePudding user response:
Inside the card-container
component emit an event with function name as parameter :
<div v-on:click="$emit('call-method',cardProperties.scrollFunction)" :id="cardProperties.id" >
<div >
<h2>{{cardProperties.title}}</h2>
<font-awesome-icon :icon="cardProperties.icon" />
<p>{{cardProperties.text}}</p>
</div>
</div>
In parent define the emitted event handler and call the method using the [] accessor like this[funcName]()
:
<card
v-for="cardProperties in cardPropsArray"
v-bind:key="cardProperties.text"
:cardProperties = cardProperties
@call-method="run"
/>
...
<script>
cardPropsArray:[
{
id: "music",
scrollFunction: "musicScroll",
title: "Musik",
icon: "fa-solid fa-music",
text: "/play"
},
{
id: "mao",
scrollFunction: "maoScroll",
title: "Med Andra Ord",
icon: "fa-solid fa-hourglass-end",
text: "/MAO"
},
...
methods:{
run(funcName){
this[funcName]();
},
....
}
</script>