0

I have a component which shows a list. This list is dynamically populated by pages using this component.

<template>
  <v-list
    subheader
  >
    <v-subheader class="font-weight-black">Choose action</v-subheader>
    <v-divider/>
    <v-list-item
      v-for="(item, i) in model.menu"
      :key="i"
      @click="item.action"
    >
      <v-list-item-title>{{ item.title }}</v-list-item-title>
    </v-list-item>
  </v-list>

</template>

And this is the TypeScript class.

<script lang="ts">
import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
import { app } from 'electron'

@Component
export default class ListItem extends Vue {
  @Prop() appStatus!: string
  @Prop() appId!: string

  model: any = {
    menu: [
      { title: 'Title One', action: 'someModalAction(appId)' },
      { title: 'Title Two', action: '' },
      { title: 'Title Three', action: '' }
    ]
  }

  someModalAction( appId: string ) {
    // show some modal here
  }
</script>

Here model object would be dynamic and other pages would pass this object as Prop() (This is just an example here).

When I click on Title One, nothing happens. However, when I change the object to

{title: 'Title One', action: this.someModalAction(this.appId)}

Then I can see the modal when the page is loaded. When I close this modal, the list item cannot be clicked then.

So, how can I pass actions to @click dynamically?

5
  • did you tried @click="item.action()"? Commented Jan 28, 2020 at 11:51
  • or even @click=item.action(i) since there is a parameter appId? Commented Jan 28, 2020 at 11:52
  • @depperm i is just the index here. I was hoping to just put this string 'someModalAction(appId)' in @click, but somehow that doesn't work. Commented Jan 28, 2020 at 12:08
  • @EmīlsGulbis Yeah, this didn't work. Commented Jan 28, 2020 at 12:10
  • what I'm saying is your function takes a parameter and I don't know what appId is or where it comes from but it needs to be passed Commented Jan 28, 2020 at 12:25

3 Answers 3

1

convert data with getter:

import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
import { app } from 'electron'

@Component
export default class ListItem extends Vue {
  @Prop() appStatus!: string
  @Prop() appId!: string

  model: any = {
    menu: [
      { title: 'Title One', action: 'someModalAction' },
      { title: 'Title Two', action: '' },
      { title: 'Title Three', action: '' }
    ]
  }
  get items(){
    return this.model.menu

    .map(item => ({...item, action: item.action && () => this[item.action](this.appId)})
  }

  someModalAction( appId: string ) {
    // show some modal here
  }
<template>
  <v-list
    subheader
  >
    <v-subheader class="font-weight-black">Choose action</v-subheader>
    <v-divider/>
    <v-list-item
      v-for="(item, i) in items"
      :key="i"
      @click="item.action"
    >
      <v-list-item-title>{{ item.title }}</v-list-item-title>
    </v-list-item>
  </v-list>

</template>
Sign up to request clarification or add additional context in comments.

Comments

1

Just make one function for calling you function on click.

To use dynamic function call it is suggested to have a helper function that receives the function name and call the corresponding function.

  data () {
    return {
      test: '',
      submitting: false,
       list: [{
        title: "One",
        action: "itemClicked"
      },
      {
        title: "Two",
        action: "itemClicked2"
      },
      {
        title: "Three",
        action: "itemClicked3"
      }
    ]
    }
  },
methods: {
    itemClicked() {
      alert('item clicked')
    },
    itemClicked2() {
      alert('item clicked 2')
    },
    itemClicked3() {
      alert('item clicked 3')
    },
    funcioncall(name){
      this[name]();
    }
  }

codepen - https://codepen.io/Pratik__007/pen/JjoVxbj?editors=1010

4 Comments

this[name]() doesn't seem to work. I get syntax errors in editor.
You can also pass appId if you want
For some reason, it's not working with TypeScript class. :/
1
v-list-item v-for="(item,index) in profileItems" @click="item.action" ripple="ripple"
                           :key="index">


{
          icon: 'mdi-exit-to-app',
          href: '/',
          title: 'Logout',
          action: () => {
            this.onUserLogout()
          }
        },
      ]

1 Comment

Hi @Kamau it would help a lot if you explained what the code does and how it solves the problem at hand

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.