In my data array, each item has a specific state
property with values of either allowed
, pending
, or rejected
. The goal is to organize the data into separate sections based on their state
, and each item also contains two buttons that can be used to change its state
.
To achieve this separation, I utilize three computed properties:
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')
}
}
The data is then displayed in distinct sections using v-for
.
When it comes to changing the state
of an item, an API call is made. To trigger this, the setState
function is employed by passing the item's id and the new state:
<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>
This is how the setState
function works:
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')
})
}
In order to update the data array in real-time, the findIndex
method is used.
While the Vue style guide recommends avoiding v-if
alongside v-for
, especially for essential elements, the question arises whether efficiency should outweigh complexity in the app:
Current Setup:
3 computed properties (O(3n)) + findIndex (O(n)) + 3 v-for loops (O(p + r + q))
Conditional v-for
:
3 conditional v-for loops (O(3n)) (omitting findIndex to directly pass index to setState
)
Code snippet for conditional v-for
:
<div v-for="(item, index) in data" v-if="item.state === 'pending'" :key="item.id">
<!-- Data card body with buttons -->
</div>
<div v-for="(item, index) in data" v-if="item.state === 'allowed'" :key="item.id">
<!-- Data card body with buttons -->
</div>
<div v-for="(item, index) in data" v-if="item.state === 'rejected'" :key="item.id">
<!-- Data card body with buttons -->
</div>