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.
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:
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:
Options
| Option | Type | Default | Notes |
|---|---|---|---|
mode | 'some' | 'every' | 'union' | 'intersection' | 'some' | Multi-query matching strategy. See Filter Modes below |
keys | string[] | — | Object keys to filter on. When omitted, all values are checked |
customFilter | (query, item) => boolean | — | Bypass built-in logic entirely with a custom predicate |
// 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:
| Mode | Behavior | Passes when |
|---|---|---|
some (default) | Iterates all queries and all values | Any query matches any value |
every | Iterates all queries and all values | All queries match all values |
union | Joins values, checks each query | Any query matches the joined string |
intersection | Joins values, checks each query | All queries match the joined string |
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/Method | Reactive | Notes |
|---|---|---|
query | ShallowRef, updated on each apply() | |
items (from apply) | Computed, filters reactively |
Reactive filtering Both the query and items passed to apply() can be reactive. The filtered result automatically updates when either changes.
Examples
Wireless Mouse
Ergonomic Bluetooth mouse with silent clicks
Mechanical Keyboard
Hot-swappable switches and RGB backlight
Noise-Cancelling Headphones
Over-ear wireless headphones with 30h battery
Studio Microphone
USB condenser mic for streaming and podcasts
Wireless Earbuds
Compact earbuds with a pocket charging case
Smart Watch
Fitness tracking, heart rate, and GPS
Fitness Band
Lightweight activity tracker with sleep insights
Ultrawide Monitor
34-inch curved display for focused work
Laptop Stand
Aluminum riser with adjustable height
Wireless Webcam
1080p camera with a built-in microphone
Mirrorless Camera
24MP sensor with 4K video recording
Camera Tripod
Carbon-fiber tripod with a quick-release ball head
FAQ
Both pass when any query matches, but some tests each field value independently while union joins all values into a single string first. The distinction matters when a match spans multiple fields.
Pass keys: ['name', 'email'] in the options. When keys is omitted, every value on the item is checked.
createFilter is pure in-memory filtering logic — reach for it for instant client-side search. When the dataset outgrows memory, or you also need sorting, pagination, and server support, move to createDataTable.
Pass a customFilter: (query, item) => boolean predicate. It bypasses keys and mode entirely, so you own the comparison — e.g. a startsWith prefix match instead of the default substring check.
mode only governs how multiple queries match, so it takes effect when the query is an array. Split a multi-word string into an array (e.g. on whitespace) to make some, every, union, and intersection behave differently.
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.