Home > front end >  Adding @click events dynamically inside v-for loop
Adding @click events dynamically inside v-for loop

Time:08-25

I have an array passed as a prop to fill in a v-for loop for a v-menu in vuetify. The menu items need to have @click events assigned and the names of the functions are passed in the array as a string (one example is the "CanResolve" event which you see in the parent component) and then inserted into the v-on:click="item.clickFunctions" for each menu button. I am currently storing the functions in the child component and it is not working but ultimately I would like to store the functions in the parent component and have the @click events call those if possible. The one example is the myButtonEventHandler method stored in the parent component which is suppose to be triggered by the CanResolve event in the child theme. For some reason this event is not even being triggered when dynamically created like this in the v-for and @click.

Child component which has the following menu which needs click events filled from array passed as prop

            <v-menu bottom
                    right>
                <template v-slot:activator="{ on, attrs }">
                    <v-btn light
                           icon
                           v-bind="attrs"
                           v-on="on">
                        <v-icon>mdi-dots-vertical</v-icon>
                    </v-btn>
                </template>
                <v-list>
                    <template v-for="(item,index) in menus">
                        <v-list-item v-if="item.isActive" :key="index" link>
                            <v-list-item-title @click="$emit(item.clickFunction)">{{item.title}}</v-list-item-title>
                        </v-list-item>
                    </template>
                    <v-list-item :href="docxLocation(filedir)" download link>
                        <v-list-item-title>Download</v-list-item-title>
                    </v-list-item>
                </v-list>
            </v-menu>

Component implemented in parent component:

<embeddedPDF @CanResolve ="myButtonEventHandler" v-bind:filedir="pdfLocation(item.Draft_Path)" v-bind:canvasid="'draft-canvas-' item.Round" :menus="menuItemsArray[item.Round-1].menus"></embeddedPDF>

CodePudding user response:

If I understood you correctly try like following snippet:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      menus: [{title: 'aaa', isActive: true, clickFunction: this.test }, {title: 'bbb', isActive: true, clickFunction: this.test}]
    }
  },
  methods: {
    test(v) {
      console.log('index '   v)
    }
  }
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
  <v-app>
    <v-main>
      <v-container>
        <v-menu bottom
                right>
            <template v-slot:activator="{ on, attrs }">
                <v-btn light
                       icon
                       v-bind="attrs"
                       v-on="on">
                    <v-icon>mdi-dots-vertical</v-icon>
                </v-btn>
            </template>
            <v-list>
                <template v-for="(item,index) in menus">
                    <v-list-item v-if="item.isActive" :key="index" link>
                        <v-list-item-title v-on:click="item.clickFunction(index)">{{item.title}}</v-list-item-title>
                    </v-list-item>
                </template>
                <v-list-item href="y" download link>
                    <v-list-item-title>Download</v-list-item-title>
                </v-list-item>
            </v-list>
        </v-menu>
      </v-container>
    </v-main>
  </v-app>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

CodePudding user response:

You need to add emit event in the child component and pass whatever you want to send to the parent as the second param.

Then in the parent component, you receive that even and assign to a function.

Child component

`

        <div v-for="{ item, idx } in items" :key="item.id">
        <button @click="$emit('handleItemClick', idx)">{{ item }}</button>
    </div>

`

parent component template


         <div>
            <ChildComponent @handleItemClick="handleChildItemClick" />
        </div>

parent component methods

    methods: {
        handleChildItemClick(idx) {
            console.log(idx);
        },
    },
  • Related