How to Create a Search Filter in Vue: Simple Guide
To create a search filter in Vue, use a
v-model on an input to bind the search text and a computed property to filter your list based on that text. This way, Vue updates the displayed items reactively as the user types.Syntax
Use v-model on an input element to bind the search text. Then create a computed property that returns a filtered list based on the search text. Finally, use v-for to display the filtered list.
v-model: binds input value to a data propertycomputed: returns filtered data reactivelyv-for: loops over filtered items to render
vue
<template> <input v-model="search" placeholder="Search..." /> <ul> <li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li> </ul> </template> <script setup> import { ref, computed } from 'vue' const search = ref('') const items = ref([ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 3, name: 'Cherry' } ]) const filteredItems = computed(() => { return items.value.filter(item => item.name.toLowerCase().includes(search.value.toLowerCase()) ) }) </script>
Output
<input placeholder="Search..." />
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</ul>
Example
This example shows a simple Vue component where you can type in the search box to filter a list of fruits. The list updates instantly as you type.
vue
<template>
<div>
<input v-model="search" placeholder="Search fruits..." aria-label="Search fruits" />
<ul>
<li v-for="fruit in filteredFruits" :key="fruit.id">{{ fruit.name }}</li>
<li v-if="filteredFruits.length === 0">No results found.</li>
</ul>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const search = ref('')
const fruits = ref([
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
{ id: 4, name: 'Date' },
{ id: 5, name: 'Elderberry' }
])
const filteredFruits = computed(() => {
return fruits.value.filter(fruit =>
fruit.name.toLowerCase().includes(search.value.toLowerCase())
)
})
</script>Output
<input placeholder="Search fruits..." aria-label="Search fruits" />
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
<li>Date</li>
<li>Elderberry</li>
</ul>
Common Pitfalls
Common mistakes include:
- Not using
toLowerCase()on both search text and item names, causing case-sensitive mismatches. - Filtering directly in the template instead of using a
computedproperty, which hurts performance. - Not binding
v-modelproperly, so the input does not update the search text.
vue
<!-- Wrong: filtering inside template --> <template> <input v-model="search" /> <ul> <li v-for="item in items.filter(i => i.name.toLowerCase().includes(search.toLowerCase()))" :key="item.id">{{ item.name }}</li> </ul> </template> <script setup> import { ref } from 'vue' const search = ref('') const items = ref([{ id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }]) </script> <!-- Right: use computed property --> <script setup> import { ref, computed } from 'vue' const search = ref('') const items = ref([{ id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }]) const filteredItems = computed(() => { return items.value.filter(item => item.name.toLowerCase().includes(search.value.toLowerCase()) ) }) </script>
Quick Reference
Tips for creating search filters in Vue:
- Use
v-modelto bind input to a reactive variable. - Use
computedproperties for efficient filtering. - Normalize text with
toLowerCase()for case-insensitive search. - Show a message when no results match.
- Keep your template clean by avoiding inline filtering.
Key Takeaways
Bind the search input with
v-model to a reactive variable.Use a
computed property to filter the list reactively and efficiently.Normalize text case with
toLowerCase() for user-friendly search.Avoid filtering directly in the template to keep performance smooth.
Provide user feedback when no items match the search.