According to the Vue documentation, a prop is passed in as a raw value that may need transformation. The recommended approach is to define a computed property using the prop's value.
If the "prop" is an array of objects, how can it be transformed into a computed array and then mutated? I followed the documentation but am unsure about mutating it.
In the example below, the component accepts an array of items
Array<{ ID: string, lettering: string; }>
. It renders buttons for each item.
- Clicking a button should change its color.
- Clicking the same button again should revert it to its initial state.
https://i.sstatic.net/nwnon.png
<template>
<div>
<button
v-for="(item, index) in selectableItems"
:key="`BUTTON-${item.ID}`"
:class="{ selected: item.selected }"
@click="() => {onButtonClicked(item, index) }"
> {{ item.lettering }}
</button>
</div>
</template>
I generate the selectableItems
from the items
array. Each item in selectableItems
has an additional property selected
along with the original properties of the item.
export default {
name: "HelloWorld",
props: {
items: Array
},
computed: {
selectableItems: function () {
const selectableItems = [];
this.items.forEach((item) => {
selectableItems.push({
ID: item.ID,
lettering: item.lettering,
selected: false
});
});
return selectableItems;
}
},
methods: {
onButtonClicked: function(item, index) {
if (item.selected) {
this.selectableItems[index].selected = false;
} else {
this.selectableItems[index].selected = true;
}
console.log(this.selectableItems);
}
}
};
The buttons in Vue do not re-render currently.
I understand that mutating the getter is not the right way to go. But what is the correct approach to mutate the array?
Forbidden solution
Passing the
{ ID: string, lettering: string; selected: boolean; }
via props
instead of { ID: string, lettering: string; }
is against the rules. { ID: string, lettering: string; }
represents the pure model and should not contain any information about UI. selected: boolean;
is strictly for UI purposes only.