Skip to main content
Vuetify0 is now a release candidate!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

createFilter

A composable for filtering arrays of items based on search queries, supporting both primitive values and complex objects with customizable filtering logic.

Usage

The createFilter composable provides reactive array filtering with multiple modes for different search behaviors. It works with both primitive values and complex objects, and supports filtering by specific keys.

ts
import { ref, shallowRef } from 'vue'
import { createFilter } from '@vuetify/v0'

const query = shallowRef('doe')
const items = ref([
  { name: 'John Doe', age: 30, city: 'New York' },
  { name: 'Jane Doe', age: 25, city: 'Los Angeles' },
  { name: 'Peter Jones', age: 40, city: 'Chicago' },
])

const filter = createFilter({ keys: ['name'] })
const { items: filtered } = filter.apply(query, items)

console.log(filtered.value)
// [
//   { name: 'John Doe', age: 30, city: 'New York' },
//   { name: 'Jane Doe', age: 25, city: 'Los Angeles' }
// ]

Context / DI

Use createFilterContext when you need to share a filter instance across a component tree:

ts
import { createFilterContext } from '@vuetify/v0'

export const [useSearchFilter, provideSearchFilter, searchFilter] =
  createFilterContext({
    namespace: 'app:search',
    mode: 'union',
    keys: ['title', 'description'],
  })

// In parent component
provideSearchFilter()

// In child component
const filter = useSearchFilter()
const { items: filtered } = filter.apply(query, products)

Returns the standard trinity [useSearchFilter, provideSearchFilter, searchFilter]. The third element gives standalone access without injection — useful for testing and server-side use.

Architecture

createFilter provides pure filtering logic with context support:

Filter Flow

Use controls to zoom and pan. Click outside or press Escape to close.

Filter Flow

Options

OptionTypeDefaultNotes
mode'some' | 'every' | 'union' | 'intersection''some'Multi-query matching strategy. See Filter Modes below
keysstring[]Object keys to filter on. When omitted, all values are checked
customFilter(query, item) => booleanBypass built-in logic entirely with a custom predicate
ts
// Filter only by name + email, using intersection mode
const filter = createFilter({
  keys: ['name', 'email'],
  mode: 'intersection',
})

// Custom filter (overrides keys and mode)
const filter = createFilter({
  customFilter: (query, item) =>
    String(item.name).toLowerCase().startsWith(String(query).toLowerCase()),
})

Filter Modes

When the query is an array, each mode controls how multiple queries are matched against item values:

ModeBehaviorPasses when
some (default)Iterates all queries and all valuesAny query matches any value
everyIterates all queries and all valuesAll queries match all values
unionJoins values, checks each queryAny query matches the joined string
intersectionJoins values, checks each queryAll queries match the joined string
Tip

some vs union some and union both pass when any query matches, but some checks each value independently while union joins all values into a single string. The difference matters when a match spans multiple fields.

Reactivity

Property/MethodReactiveNotes
queryShallowRef, updated on each apply()
items (from apply)Computed, filters reactively
Tip

Reactive filtering Both the query and items passed to apply() can be reactive. The filtered result automatically updates when either changes.

Examples

A product catalog filtered by two independent facets at once: a free-text search box and a set of category chips. The composable owns a dozen products plus the live query, match-mode, and selected-category state, then chains two createFilter instances so the visible list — and the match count beside it — stay in sync without a single hand-written watcher.

The text facet shows the mode option doing real work. Two filters are built over keys: ['name', 'description'], one in union mode and one in intersection mode, and a toRef picks whichever matches the active toggle. Splitting the query on whitespace turns multi-word input into an array, so “Any word” (union) matches products containing any term while “All words” (intersection) requires every term to appear somewhere across the searched fields. The category facet is a third createFilter in union mode, applied to the output of the text filter — apply accepts a getter, so feeding one filter’s items into the next composes the two passes into a single reactive computed.

Reach for this pattern whenever you have a fixed in-memory dataset and want instant, multi-criteria filtering with no backend round-trip. Because every apply result is a computed, the count is just results.length and clearing all facets is a plain state reset. When the dataset outgrows memory, move filtering server-side with createDataTable; to page or windowing the results, pair it with createPagination or createVirtual.

FileRole
useProductFilter.tsOwns the product data, query/mode/category state, and chains the createFilter passes into a single results computed
ProductBrowser.vueRenders the search box, mode toggle, category chips, count, and results list bound to the composable
product-browser.vueEntry point — instantiates the composable and wires its state into the browser component
Match
12 of 12 products

Wireless Mouse

Ergonomic Bluetooth mouse with silent clicks

$29Accessories

Mechanical Keyboard

Hot-swappable switches and RGB backlight

$119Accessories

Noise-Cancelling Headphones

Over-ear wireless headphones with 30h battery

$249Audio

Studio Microphone

USB condenser mic for streaming and podcasts

$89Audio

Wireless Earbuds

Compact earbuds with a pocket charging case

$149Audio

Smart Watch

Fitness tracking, heart rate, and GPS

$199Wearables

Fitness Band

Lightweight activity tracker with sleep insights

$59Wearables

Ultrawide Monitor

34-inch curved display for focused work

$449Computers

Laptop Stand

Aluminum riser with adjustable height

$39Computers

Wireless Webcam

1080p camera with a built-in microphone

$69Computers

Mirrorless Camera

24MP sensor with 4K video recording

$899Photography

Camera Tripod

Carbon-fiber tripod with a quick-release ball head

$129Photography

FAQ

Discord
Need help? Join our community for support and discussions ↗

API Reference

The following API details are for the createFilter composable.

Benchmarks

Every operation is profiled across multiple dataset sizes to measure real-world throughput. Each benchmark is assigned a performance tier—good, fast, blazing, or slow—and groups are scored by averaging their individual results so you can spot bottlenecks at a glance. This transparency helps you make informed decisions about which patterns scale for your use case. Learn more in the benchmarks guide.

View benchmark source↗

Was this page helpful?

Ctrl+/