I have been looking around and found that the most common solution to my problem is to set a variable with the instance of the app/component and then using this variable to change the data (Example 1, Example 2).
My issue is that I cannot use arrow functions (I am only allowed to use ES5 comptible JS, not my call) and that my function does not have a "previous" part to set the app instance.
var theApp = new Vue({
el: '#the-app',
data: {
selectedView: 1,
myDynamicButtonsArray: [
{
text: 'Change view!!'
onClick: function () {
// here this.selectedView should be changed
this.selectedView = 2;
}
},
{
text: 'My other button'
onClick: function () {
// Here something completely unrelated should happen
}
}
]
}
});
The I loop over myDynamicButtonsArray and load a myButton component that executes the onClick when clicked.
<my-button v-for="button in myDynamicButtonsArray" v-bind="button"></my-button>
The problem is that when I execute this.selectedView = 2; the this is not refering to the app instance but the function instance where it is being executed, makes sense.
I have tried setting the value like this:
theApp._data.selectedView = 2;
But I am not sure if this is the right approach.
The reason why I am not using the $emit is because there are many different functions to be executed, and emiting a button-clicked and then executing a common function with a giant switch so it does one thing or another depending on what button was pressed does not seem like a viable solution:
// MyButton component template
<button @onClick="this.$emit('button-clicked', id)">
{{ text }}
</button>
// App html
<my-button
v-for="button in myDynamicButtonsArray"
v-bind="button"
@button-clicked="buttonClicked"
>
</my-button>
// App object
var theApp = new Vue({
el: '#the-app',
data: {
selectedView: 1,
myDynamicButtonsArray: [
{
text: 'Change view!!',
id: 1
},
{
text: 'My other button',
id: 2
}
]
},
methods: {
buttonClicked: function(id) {
switch(id) {
case 1:
this.selectedView = 2;
// I am not even sure if I can use 'this' the way I want here;
break;
case 2:
// And so on for all my buttons
}
}
}
});
And emitting a different event per button does also not seem viable:
// MyButton component template
<button @onClick="this.$emit(customEventString)">
{{ text }}
</button>
// App html
<my-button
v-for="button in myDynamicButtonsArray"
v-bind="button"
@custom-event-1="customEvent1"
@custom-event-2="customEvent2"
>
</my-button>
// App object
var theApp = new Vue({
el: '#the-app',
data: {
selectedView: 1,
myDynamicButtonsArray: [
{
text: 'Change view!!',
customEventString: 'custom-event-1'
},
{
text: 'My other button',
customEventString: 'custom-event-2'
}
]
},
methods: {
customEvent1: function() {
this.selectedView = 2;
// I am not even sure if I can use 'this' the way I want here;
},
customEvent2: function() {
// Do other things
}
}
});
My question is, which is the right approach:
- Using
myApp._data - Having one event and a
switchinside - Or something else
onClickfunction to vue's methods and rename it to eg "myButtonOne" or something. Then have the function name as string inside themyDynamicButtonsArrayinstead. This way you could run the function on the button like so:@click="this['myButtonOne']()"?