Reputation: 3411
I’m not sure if it’s possible but what I’m tying to do is to pass a method name in a variable to grandchild.
On my page there is “topbar” component, which contains “button” component.
// Home.vue
<my-topbar :buttons="buttons"></my-topbar>
data() {
return {
buttons: [
{
type: "icon",
icon: "delete",
label: "delete",
method: "deleteSelections",
},
{
type: "icon",
icon: "upload",
label: "upload",
method: "saveToDatabase",
}
]
};
},
// Topbar.vue
<my-button v-for="(button, index) in buttons" :key="index" :button="button"></my-button>
// Button.vue
<v-btn @click="button.method">
<v-icon v-if="button.type !== 'text'">{{icons[button.icon]}}</v-icon>
<span v-if="button.type !== 'icon'">{{$t(`buttons[${button.label}]`)}}</span>
</v-btn>
My problem is @click=“button.method” part. When I click it, it returns: “TypeError: _vm.button.method is not a function”
I tried these 2 syntax but couldn’t get any result, not even an error in this case:
:on-click="${button.method}"
@click="${button.method}"
I appreciate that if someone can tell me the correct way of doing this. Thanks.
Upvotes: 1
Views: 2118
Reputation: 2421
Forgive the lack of styling, and I can't figure out why the text isn't showing up on the button. But - here's what I did.
Pass the buttons
array to the header, as you're doing now. in Button.vue
add a @click
handler to call a proxy method callMethod(button.method)
. The important part is this proxy method:
methods: {
saveToDatabase() {
console.log("Save to database!");
},
deleteSelections() {
console.log("Delete seleciton!");
},
callMethod(method) {
this[method]();
}
The callMethod
in its entirety is this[method]()
. As long as the method passed in exists in the component's methods, it will call it. this
in this case refers to the component. The brackets will call the evaluated value of whatever's passed in. Here's an explanation on that: https://stackoverflow.com/a/45173791/7375929
Upvotes: 3