Fuse.js
This guide plugs Fuse.js into VPick for fuzzy search: a misspelled query still finds its option, and the closest matches come first.
Demo
Search for "lovlace", "hoper" or "kernel".
[]
Approach
- Fuse.js runs in the page, over options you already have.
fetchOptionshands the query to Fuse and returns its results in Fuse's order.searchDebounceis0, so the list updates on every keystroke.optionsholds the full list, shown before anything is typed.
Anatomy
<script setup>
import Fuse from "fuse.js"
const fuse = new Fuse(people, { keys: ["name", "email"] })
function fetchOptions(query) {
return fuse.search(query).map((result) => result.item)
}
</script>
<template>
<VPick
:options="people"
:fetch-options="fetchOptions"
:search-debounce="0"
label-key="name"
value-key="id"
/>
</template>Setup
Install
npm install fuse.jsBuild the index
Create one Fuse instance for your list, outside anything that re-renders. keys lists the fields to search.
const fuse = new Fuse(people, {
keys: ["name", "email"],
threshold: 0.4,
})Connect it to VPick
Fuse returns wrapper objects. Hand VPick the original items inside them:
function fetchOptions(query) {
return fuse.search(query).map((result) => result.item)
}Then pass fetchOptions, set searchDebounce to 0, and point labelKey and valueKey at your fields, as in the anatomy above.
Tuning
- How forgiving.
thresholdruns from0(exact) to1(anything matches). Around0.3to0.4suits names. Higher lets more loose matches in, which starts to crowd the list. - Which fields matter most. Give keys a weight:
keys: [{ name: "name", weight: 2 }, "email"]. - How many results.
fuse.search(query, { limit: 20 })keeps long lists short.
When the list changes
If people changes, rebuild the index with fuse.setCollection(people), or create a new Fuse. VPick keeps each query's results, so pass a new fetchOptions function at the same time: a new function clears those results.
Selections
Picked options keep their chip or label after a later search stops returning them. Put already-selected people in options so they have a label before any search runs.