I have a data array, and each item in the array has a state property that contains one of these values, allowed, pending, rejected. I want to display data in separate sections based on their state. Each data card has two buttons on it that can be used to change item state.
I'm using three computed properties to separate data like so:
computed: {
pendingData() {
return this.data.filter(x => x.state === 'pending')
},
allowedData() {
return this.data.filter(x => x.state === 'allowed')
},
rejectedData() {
return this.data.filter(x => x.state === 'rejected')
}
}
and I display them in their own section using v-for.
Changing state occurs through an API call, so I need to send the id of item and new state to setState function:
<div class="state-change-buttons">
<button @click="setState(item.id, 'allowed')">
<span uk-icon="icon: check; ratio: 1.4"></span>
</button>
<button @click="setState(item.id, 'pending')">
<span uk-icon="icon: future; ratio: 1.4"></span>
</button>
</div>
and this is setState function:
setState(id, state) {
const index = this.data.findIndex(x => x.id === id)
this.$axios.post(`/api/${id}`, {state})
.then(res => {
this.data.splice(index, 1, res.data)
})
.catch(err => {
this.$notify(err, 'danger')
})
}
As you can see, to update my data array in realtime I have to find the index of selected item using findIndex.
Vue style guide suggests not to use v-if on the same element as v-for. But should I still avoid it, even if it decreases my app, time complexity?
current scenario:
3 computed property (O(3n)) + findIndex (O(n)) + 3 v-for (O(p + r + q))
conditional v-for:
3 conditional v-for (O(3n)) (no findIndex, this way I can pass index to setState directly)
conditional v-for code:
<div v-for="(item, index) in data" v-if="item.state === 'pending'" :key="item.id">
<!-- data card body (including buttons) -->
</div>
<div v-for="(item, index) in data" v-if="item.state === 'allowed'" :key="item.id">
<!-- data card body (including buttons) -->
</div>
<div v-for="(item, index) in data" v-if="item.state === 'rejected'" :key="item.id">
<!-- data card body (including buttons) -->
</div>
v-ifandv-forfit in your template, can you add that? Because from what I'm seeing and understanding, they shouldn't be on the same root element either way.