I have a Vue.js component page that gets some data from my backend:
<script setup>
const props = defineProps({
records: {
type: Object,
},
});
</script>
I have three different filters/states which I want my users to be able to select from:
- Unlablled
- Completed
- Skipped
Below is how I get the records for the different filters. I am using collect.js to make working with the object easier:
let getRecords = () => {
return collect(props.records)
}
const getUnlabeledRecords = () => {
return getRecords()
.where('skipped', false)
.where('processed', false);
}
const getCompletedRecords = () => {
return getRecords()
.where('processed', true);
}
const getSkippedRecords = () => {
return getRecords()
.where('processed', false)
.where('skipped', true);
}
//Load all records on page load.
const allRecords = ref(getUnlabeledRecords());
//Show current record to the user.
const current = ref(allRecords.value.first());
My users can then click on the filter they want:
<a :class="{'bg-gray-100' : currentFilter === 'Unlabeled' }"
@click="allRecords = getUnlabeledRecords(), currentFilter = 'Unlabeled'">
Unlabeled ({{ getUnlabeledRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Skipped' }"
@click="allRecords = getSkippedRecords(), currentFilter = 'Skipped'">
Skipped ({{ getSkippedRecords().count() }})
</a>
<a :class="{'bg-gray-100' : currentFilter === 'Completed' }"
@click="allRecords = getCompletedRecords(), currentFilter = 'Completed'">
Completed ({{ getCompletedRecords().count() }})
</a>
The above code works, but it feels very "clunky", and not very scaleable. Say, I want to introduce more advanced filtering - or just other "filter options", I have to duplicate a lot of code.
Anyone have suggestions on how I can do this in a better way?