Choices.js全文搜索仅匹配首词 无法匹配非开头位置关键词问题
问题描述
使用 choices.js 库实现下拉菜单搜索功能时,搜索框输入内容后,建议列表仅展示首词精确匹配的数据,无法匹配关键词出现在任意位置的选项。
示例现有选项如下:
[mid america, america ]
搜索 america 时,下拉列表仅展示 america 选项,不会展示同样包含该关键词的 mid america 选项。
当前使用的choices.js搜索过滤配置如下:
silent: false, items: [], choices: [], renderChoiceLimit: -1, maxItemCount: -1, addItems: true, addItemFilter: null, removeItems: true, removeItemButton: false, editItems: false, allowHTML: true, duplicateItemsAllowed: true, delimiter: ',', paste: true, searchEnabled: true, searchChoices: true, searchFloor: 1, searchResultLimit: 4, searchFields: ['label', 'value'], position: 'auto', resetScrollPosition: true, shouldSort: true, shouldSortItems: false, sorter: () => {...}, placeholder: true, placeholderValue: null, searchPlaceholderValue: null, prependValue: null, appendValue: null, renderSelectedChoices: 'auto', loadingText: 'Loading...', noResultsText: 'No results found', noChoicesText: 'No choices to choose from', itemSelectText: 'Press to select', addItemText: (value) => { return `Press Enter to add <b>"${value}"</b>`; }, maxItemText: (maxItemCount) => { return `Only ${maxItemCount} values can be added`; }, valueComparer: (value1, value2) => { return value1 === value2; }, classNames: { containerOuter: 'choices', containerInner: 'choices__inner', input: 'choices__input', inputCloned: 'choices__input--cloned', list: 'choices__list', listItems: 'choices__list--multiple', listSingle: 'choices__list--single', listDropdown: 'choices__list--dropdown', item: 'choices__item', itemSelectable: 'choices__item--selectable', itemDisabled: 'choices__item--disabled', itemChoice: 'choices__item--choice', placeholder: 'choices__placeholder', group: 'choices__group', groupHeading: 'choices__heading', button: 'choices__button', activeState: 'is-active', focusState: 'is-focused', openState: 'is-open', disabledState: 'is-disabled', highlightedState: 'is-highlighted', selectedState: 'is-selected', flippedState: 'is-flipped', loadingState: 'is-loading', noResults: 'has-no-results', noChoices: 'has-no-choices' }, // Choices使用Fuse库实现搜索功能 fuseOptions: { includeScore: true }
需要调整配置,实现搜索时匹配选项任意位置包含关键词的结果。
解决方案
问题根源是choices.js依赖的Fuse搜索库默认采用前缀匹配逻辑,仅优先命中关键词出现在字符串开头的结果。只需修改fuseOptions配置项,调整匹配规则即可支持任意位置关键词命中:
fuseOptions: { includeScore: true, location: 0, threshold: 0.2, distance: 10000, matchAllTokens: true, findAllMatches: true }
配置说明:
distance: 10000:将匹配距离设置为足够大的值,取消关键词必须出现在字符串开头附近的限制findAllMatches: true:搜索时遍历整个字符串查找所有匹配项,不会在匹配到开头结果后就停止检索matchAllTokens: true:确保拆分后的搜索关键词全部命中才返回结果,避免无关结果混入
如果不需要模糊搜索容错(比如输错字符也返回结果),可以额外添加配置实现精准的任意位置包含匹配:
fuseOptions: { includeScore: true, location: 0, threshold: 0, // 阈值设为0,关闭模糊容错,必须完全匹配关键词 distance: 10000, matchAllTokens: true, findAllMatches: true, isCaseSensitive: false, // 不区分大小写 minMatchCharLength: 1 }
调整完成后,搜索america时,mid america和america都会出现在下拉结果列表中。
内容的提问来源于stack exchange,提问作者Darshan Thakor
相关产品推荐
相关产品推荐

