Home > Back-end >  How do i get a different onclick event on each object when looping through an array of objects VUE3
How do i get a different onclick event on each object when looping through an array of objects VUE3

Time:11-16

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>
  • Related