0

I want to create components in a loop, passing properties to the child by name.

so: <card-base v-for="(card, i) in cards" :key="i" :heading="card.heading" :width="card.width" class="dashboard-card" :cardHeaderButtons="[{icon: 'minimize', fn: 'minimizeDashboardCard'}]">

in my (child!) component i have defined the minimizeDashboardCard method, and

                <v-btn icon flat class="header-button" v-for="(button, i) in cardHeaderButtons"
                       :key="i"
                       v-if="$vuetify.breakpoint.lgAndUp"
                       color="white"
                       @click.capture.stop="button.fn"
                >
                    <v-icon>
                        {{ button.icon }}
                    </v-icon>
                </v-btn>

the {{ button.icon }} works. but the fn doesn't

Uncaught TypeError: button.fn is not a function
    at !click (CardBase.vue?ac7a:32)
    at invoker (vue.esm.js?efeb:2027)
    at HTMLButtonElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1826)

i also tried with this[button.fn], but that doesn't work either.

the solution is probably super easy, but i don't see it right now. how can i pass the method NAME? (like for minimize, i want to have methods defined once in that card component and just have to pass the name to reuse it.)

thanks :)

2
  • 1
    As you have it now, button.fn is defined as a string. If minimizeDashboardCard is a method in the parent scope, just pass the function. fn: minimizeDashboardCard Commented Nov 26, 2018 at 21:48
  • but minimizeDashboardCardis only defined in the child. that's why i want to pass strings and not define the "minimize" method in every place i use it around the app. (edited the original question to make it clear the method is only defined in the child method) Commented Nov 26, 2018 at 21:50

3 Answers 3

4

How about using a helper method ..

methods: {
  ...
  call(methodName) {
    this[methodName]()
  }
}

Then you can do this in your template ..

 <v-btn icon flat class="header-button" v-for="(button, i) in cardHeaderButtons"
                       :key="i"
                       v-if="$vuetify.breakpoint.lgAndUp"
                       color="white"
                       @click.capture.stop="call(button.fn)"
>
Sign up to request clarification or add additional context in comments.

Comments

1

maybe try @click.capture.stop="eval(button.fn).call()"

https://www.w3schools.com/js/js_function_call.asp

2 Comments

unfortunately not :/ Uncaught TypeError: button.fn.call is not a function at !click (CardBase.vue?ac7a:32) at invoker (vue.esm.js?efeb:2027) at HTMLButtonElement.fn._withTask.fn._withTask (vue.esm.js?efeb:1826) (both with and without parens)
works now, but i think it's cleaner with a helper function. but thanks for your help :)
1

pass button as parameter to a method like :

   @click.capture.stop="callBtn(button)"

in your methods :

  methods:{
      callBtn(button){
       button.fn();
       }
    ...  
     }

1 Comment

didn't work, it would still try to "call" fn (which is a string). in connection with Husam's answer, it worked now though. thanks to all of you!

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.