calling function stored as a property in an object in a for loop

Viewed 28

In my template i'm rendering a v-list using a v-for.

<v-list dense>
  <template v-for="(menuItem, index) in menuItems">
    <v-list-item :key="index" @click.stop="menuItem.function">
      <v-list-item-icon>
        <v-icon :color="menuItem.color">{{ menuItem.icon }}</v-icon>
      </v-list-item-icon>
      <v-list-item-title> {{ menuItem.title }} </v-list-item-title>
    </v-list-item>
  </template>
</v-list>

in my script section i'm doing this

data: () => ({
    menuItems: [
        {
            title: 'Lijst samenklappen',
            icon: 'mdi-arrow-top-left-thin-outline',
            color: 'grey',
            function: 'collapse'
        },
        {
            title: 'Onderdeel toevoegen',
            icon: 'mdi-plus-circle',
            color: 'green',
            function: 'add'
        },
        {
            title: 'Bestaand onderdeel toevoegen',
            icon: 'mdi-plus-circle',
            color: 'green',
            function: 'addExisting'
        },
        {
            title: 'Dit onderdeel verwijderen',
            icon: 'mdi-minus-circle',
            color: 'red',
            function: 'disable'
        }
    ]
}),
methods: {
    cardClick() {
        this.$nuxt.$emit('set-part', this.tab)
    },
    add() {
        this.$nuxt.$emit('add-part', this.part.PK_R_ASSEMBLY)
    },
    addExisting() {
        this.$nuxt.$emit('add-existing-part', this.part.PK_R_ASSEMBLY)
    },
    disable() {
        this.$nuxt.$emit('disable-part', this.part.PK_R_ASSEMBLY)
    },
    collapse() {
        this.$nuxt.$emit('collapse', this.tab.PK_R_ASSEMBLYDETAILSUBASSEMBLY)
    },
    open() {
        this.$nuxt.$emit('open', this.tab.PK_R_ASSEMBLYDETAILSUBASSEMBLY)
    }
}

I've tried several way's to try and call the function by the property value in the object. No luck

Does anybody have an idea how to do this? Not all code is displayed, as I don't think it is relevant to the question.

2 Answers

You can change your click event like this:

 @click.stop="handleEvents(menuItem.function)"

And add a new function to your methods object to call functions:

methods: {
   handleEvents(funcName) {
     this[funcName]()
   } 
}

You could create a generic function like menuMethod(action, part) with the following

menuMethod({ action, part }) {
  this.$emit(action, this[part])
}

and call it like that in the template

<v-list-item
  :key="menuItem.title"
  @click.stop="menuMethod({ action: menuItem.function, part: menuItem.part })"
>

with an update to your object like

{
  title: 'Dit onderdeel verwijderen',
  icon: 'mdi-minus-circle',
  color: 'red',
  function: 'disable',
  part: 'part.PK_R_ASSEMBLY'
}
Related