How to filter a table in Vue
Implementing table filtering allows users to narrow down data based on search terms and criteria, essential for data-heavy Vue applications. As the creator of CoreUI with over 11 years of Vue development experience since 2014, I’ve built advanced filtering systems in countless enterprise tables. The most effective solution is to use reactive state for filter criteria and computed properties to apply filtering logic. This approach provides real-time, efficient filtering with support for multiple conditions.
Use computed properties to filter table data in Vue 3.
<template>
<div>
<div class='filters'>
<input
v-model='searchTerm'
type='text'
placeholder='Search by name or email...'
/>
<select v-model='statusFilter'>
<option value=''>All Status</option>
<option value='active'>Active</option>
<option value='inactive'>Inactive</option>
</select>
<input
v-model.number='minAge'
type='number'
placeholder='Min age'
/>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Age</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for='item in filteredData' :key='item.id'>
<td>{{ item.name }}</td>
<td>{{ item.email }}</td>
<td>{{ item.age }}</td>
<td>{{ item.status }}</td>
</tr>
</tbody>
</table>
<p>Showing {{ filteredData.length }} of {{ data.length }} items</p>
</div>
</template>
<script>
import { ref, computed } from 'vue'
export default {
setup() {
const searchTerm = ref('')
const statusFilter = ref('')
const minAge = ref(0)
const data = ref([
{ id: 1, name: 'John Doe', email: '[email protected]', age: 30, status: 'active' },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 25, status: 'inactive' },
{ id: 3, name: 'Bob Johnson', email: '[email protected]', age: 35, status: 'active' }
])
const filteredData = computed(() => {
return data.value.filter(item => {
const matchesSearch = !searchTerm.value ||
item.name.toLowerCase().includes(searchTerm.value.toLowerCase()) ||
item.email.toLowerCase().includes(searchTerm.value.toLowerCase())
const matchesStatus = !statusFilter.value || item.status === statusFilter.value
const matchesAge = item.age >= minAge.value
return matchesSearch && matchesStatus && matchesAge
})
})
return { searchTerm, statusFilter, minAge, data, filteredData }
}
}
</script>
The filter inputs are bound to reactive refs using v-model. A computed property filters the data array based on all active criteria using AND logic. Each filter condition checks if the filter is set before applying it, allowing optional filtering. The search term filters across multiple fields using the includes method with case-insensitive matching.
Best Practice Note
This is the same filtering implementation we use in CoreUI Vue tables for flexible data filtering. For better performance with large datasets, consider debouncing the search input or implementing server-side filtering. Add a clear filters button to reset all criteria simultaneously for improved user experience.



