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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs