0
0
VueHow-ToBeginner · 3 min read

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 property
  • computed: returns filtered data reactively
  • v-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 computed property, which hurts performance.
  • Not binding v-model properly, 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-model to bind input to a reactive variable.
  • Use computed properties 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.