JAVASCRIPT
Composable for Client-Side Filtering and Sorting Data
Implement a reusable Vue 3 Composable to efficiently filter and sort local array data based on user input, enhancing dynamic list displays.
// composables/useFilteredAndSortedData.js
import { ref, computed } from 'vue';
export function useFilteredAndSortedData(initialData) {
const data = ref(initialData);
const searchTerm = ref('');
const sortKey = ref(null);
const sortOrder = ref(1); // 1 for ascending, -1 for descending
const filteredData = computed(() => {
if (!searchTerm.value) {
return data.value;
}
const searchLower = searchTerm.value.toLowerCase();
return data.value.filter(item =>
Object.values(item).some(value =>
String(value).toLowerCase().includes(searchLower)
)
);
});
const sortedAndFilteredData = computed(() => {
let currentData = [...filteredData.value];
if (sortKey.value) {
currentData.sort((a, b) => {
const valA = a[sortKey.value];
const valB = b[sortKey.value];
if (typeof valA === 'string' && typeof valB === 'string') {
return valA.localeCompare(valB) * sortOrder.value;
}
return (valA - valB) * sortOrder.value;
});
}
return currentData;
});
const setSort = (key) => {
if (sortKey.value === key) {
sortOrder.value *= -1; // Toggle order if same key
} else {
sortKey.value = key;
sortOrder.value = 1; // Default to ascending for new key
}
};
return {
data, // Original data (can be updated)
searchTerm,
sortKey,
sortOrder,
sortedAndFilteredData,
setSort
};
}
// MyDataTable.vue
<template>
<div>
<input v-model="searchTerm" placeholder="Search..." />
<button @click="setSort('name')">Sort by Name</button>
<button @click="setSort('age')">Sort by Age</button>
<ul>
<li v-for="item in sortedAndFilteredData" :key="item.id">
{{ item.name }} ({{ item.age }})
</li>
</ul>
</div>
</template>
<script setup>
import { useFilteredAndSortedData } from '@/composables/useFilteredAndSortedData'; // Adjust path
const initialUsers = [
{ id: 1, name: 'Alice', age: 30 },
{ id: 2, name: 'Bob', age: 24 },
{ id: 3, name: 'Charlie', age: 35 },
{ id: 4, name: 'David', age: 24 },
];
const { searchTerm, setSort, sortedAndFilteredData } = useFilteredAndSortedData(initialUsers);
</script>
How it works: This composable `useFilteredAndSortedData` provides reactive logic for filtering and sorting an array of objects. It takes initial data, exposes `searchTerm`, `sortKey`, and `sortOrder` as refs, and provides computed properties `filteredData` and `sortedAndFilteredData`. The `setSort` function toggles sorting order or applies a new sort key. This pattern allows for clean, reusable data manipulation logic that can be easily integrated into any Vue component for dynamic list displays.