分大小寫(xiě)篩選:基于 filterOption 自定義搜索匹配實(shí)戰(zhàn)指南)
ant-design AutoComplete 不區(qū)分大小寫(xiě)篩選基于 filterOption 自定義搜索匹配實(shí)戰(zhàn)指南【免費(fèi)下載鏈接】ant-designAn enterprise-class UI design language and React UI library項(xiàng)目地址: https://gitcode.com/gh_mirrors/ant/ant-designAutoComplete 是 ant-design 數(shù)據(jù)錄入組件中的帶提示的文本輸入框其內(nèi)置的默認(rèn)篩選邏輯是區(qū)分大小寫(xiě)的字符串匹配。本篇指南以components/auto-complete/demo/non-case-sensitive.tsx演示為骨架完整講解如何通過(guò)filterOption回調(diào)自定義匹配規(guī)則實(shí)現(xiàn)不區(qū)分大小寫(xiě)case-insensitive的選項(xiàng)過(guò)濾并深入源碼分析該回調(diào)的調(diào)用時(shí)機(jī)、參數(shù)結(jié)構(gòu)與實(shí)現(xiàn)原理同時(shí)給出實(shí)際可復(fù)制的完整代碼示例。一、演示場(chǎng)景定位官方不區(qū)分大小寫(xiě)示例在 ant-design 倉(cāng)庫(kù)中AutoComplete 的演示文件與說(shuō)明文檔成對(duì)出現(xiàn)說(shuō)明文檔components/auto-complete/demo/non-case-sensitive.md中文標(biāo)題為不區(qū)分大小寫(xiě)的 AutoComplete實(shí)現(xiàn)源碼components/auto-complete/demo/non-case-sensitive.tsx。該示例在組件文檔首頁(yè)components/auto-complete/index.zh-CN.md中登記為不區(qū)分大小寫(xiě)演示項(xiàng)對(duì)應(yīng)的code src./demo/non-case-sensitive.tsx標(biāo)簽表明它會(huì)直接渲染進(jìn)文檔頁(yè)面是可交互的真實(shí)示例。示例的業(yè)務(wù)場(chǎng)景非常典型當(dāng)選項(xiàng)為街道名稱等英文文本如Burns Bay Road、Downing Street、Wall Street時(shí)用戶習(xí)慣用小寫(xiě)字母輸入如b此時(shí)默認(rèn)的區(qū)分大小寫(xiě)篩選會(huì)過(guò)濾掉全部大寫(xiě)開(kāi)頭的選項(xiàng)導(dǎo)致明明存在卻搜不到。本示例正是為解決這一用戶體驗(yàn)問(wèn)題而生。二、完整代碼解析filterOption 實(shí)現(xiàn)不區(qū)分大小寫(xiě)2.1 官方示例源碼以下為 components/auto-complete/demo/non-case-sensitive.tsx 的完整實(shí)現(xiàn)import React from react; import { AutoComplete } from antd; const options [ { value: Burns Bay Road }, { value: Downing Street }, { value: Wall Street }, ]; const App: React.FC () ( AutoComplete style{{ width: 200 }} options{options} placeholdertry to type b filterOption{(inputValue, option) option!.value.toUpperCase().indexOf(inputValue.toUpperCase()) ! -1 } / ); export default App;2.2 核心邏輯逐行拆解數(shù)據(jù)源options使用數(shù)據(jù)化配置方式每項(xiàng)僅包含value字段。AutoComplete 的options類(lèi)型為{ label, value }[]當(dāng)label缺省時(shí)下拉列表直接展示value文本。占位提示placeholdertry to type \b引導(dǎo)用戶輸入小寫(xiě)字母b直觀驗(yàn)證不區(qū)分大小寫(xiě)的效果——輸入b 時(shí)三條街道名全部命中。自定義篩選filterOption接收兩個(gè)參數(shù)(inputValue, option)inputValue用戶當(dāng)前輸入框中的文本option待匹配的選項(xiàng)對(duì)象含value等字段。匹配算法option!.value.toUpperCase().indexOf(inputValue.toUpperCase()) ! -1。思路是先把待匹配文本與輸入文本統(tǒng)一轉(zhuǎn)換為大寫(xiě)再做子串包含判斷。toUpperCase()保證比較時(shí)大小寫(xiě)被抹平indexOf(...) ! -1表示包含即命中而非前綴匹配——因此輸入street同樣能命中Downing Street、Wall Street。option!的非空斷言是在明確 option 存在的前提下避免 TS 報(bào)錯(cuò)。2.3 兩種等價(jià)寫(xiě)法除官方示例的toUpperCase寫(xiě)法外也可以使用toLowerCase語(yǔ)義完全等價(jià)filterOption{(inputValue, option) option!.value.toLowerCase().includes(inputValue.toLowerCase()) }在 Select 組件的同類(lèi)示例 components/select/demo/search-filter-option.tsx 中官方正是采用toLowerCaseincludes的組合對(duì)label字段做不區(qū)分大小寫(xiě)的子串匹配可作為交叉參考。三、filterOption 的完整參數(shù)語(yǔ)義與使用場(chǎng)景根據(jù) components/auto-complete/index.zh-CN.md 的 API 說(shuō)明filterOption的完整定義如下參數(shù)說(shuō)明類(lèi)型默認(rèn)值filterOption是否根據(jù)輸入項(xiàng)進(jìn)行篩選。當(dāng)其為一個(gè)函數(shù)時(shí)會(huì)接收inputValueoption兩個(gè)參數(shù)當(dāng)option符合篩選條件時(shí)應(yīng)返回true反之則返回falseboolean \| function(inputValue, option)true3.1 默認(rèn)值true的語(yǔ)義默認(rèn)值為true時(shí)AutoComplete 使用 rc-select 內(nèi)置的默認(rèn)篩選函數(shù)其行為是對(duì)option.value做區(qū)分大小寫(xiě)的子串包含匹配底層通過(guò)indexOf實(shí)現(xiàn)未做大小寫(xiě)歸一化。這就是為什么默認(rèn)情況下輸入小寫(xiě)b無(wú)法命中Burns Bay Road——這正是本節(jié)示例需要自定義filterOption的根本原因。3.2 傳false的語(yǔ)義當(dāng)傳入false時(shí)AutoComplete 不做任何本地過(guò)濾配合onSearch回調(diào)進(jìn)行服務(wù)端或異步搜索見(jiàn)下文 5.1 節(jié)的自定義搜索模式。3.3 函數(shù)形式完全控制匹配規(guī)則傳入函數(shù)即完全接管篩選邏輯可自由實(shí)現(xiàn)不區(qū)分大小寫(xiě)匹配本示例核心filterOption{(inputValue, option) option!.value.toUpperCase().includes(inputValue.toUpperCase()) }對(duì) label 而非 value 匹配當(dāng) options 配置了label時(shí)filterOption{(inputValue, option) (option?.label ?? ).toLowerCase().includes(inputValue.toLowerCase()) }注意option參數(shù)的類(lèi)型在 TS 下可能為可選需用option?.label或option!做空值處理官方示例components/select/demo/search-filter-option.tsx即采用(option?.label ?? )的防御寫(xiě)法。多字段聯(lián)合匹配同時(shí)匹配 value 與自定義字段filterOption{(inputValue, option) [option?.value, option?.label].some( (field) field?.toLowerCase().includes(inputValue.toLowerCase()), ) }四、源碼級(jí)原理AutoComplete 與 Select 的關(guān)系從實(shí)現(xiàn)源碼 components/auto-complete/index.tsx 可以確認(rèn)AutoComplete 并不是獨(dú)立實(shí)現(xiàn)的下拉組件而是對(duì) Select 的封裝第 135-153 行AutoComplete 最終渲染Select并通過(guò)suffixIcon{null}去掉下拉箭頭、以SECRET_COMBOBOX_MODE_DO_NOT_USE內(nèi)部模式實(shí)現(xiàn)自由輸入 補(bǔ)全提示的 combobox 交互filterOption等下拉相關(guān)屬性經(jīng)由{...omit(props, [dataSource, dropdownClassName])}原樣透?jìng)鹘o Select再透?jìng)鹘o底層 rc-select 的搜索過(guò)濾邏輯因此filterOption的匹配邏輯在 AutoComplete 與 Select開(kāi)啟showSearch時(shí)中行為一致兩者可互相參考——例如 components/select/demo/search-filter-option.tsx 中 Select 的搜索過(guò)濾實(shí)現(xiàn)方式同樣適用于 AutoComplete。從渲染快照 components/auto-complete/tests/snapshots/demo.test.tsx.snap 可以看到該示例實(shí)際渲染出的 DOM 攜帶ant-select-auto-complete ant-select-single ant-select-show-search等類(lèi)名進(jìn)一步印證 AutoComplete 基于 Select 搜索模式的實(shí)現(xiàn)事實(shí)。4.1 一個(gè)值得注意的行為細(xì)節(jié)根據(jù)組件文檔 FAQcomponents/auto-complete/index.zh-CN.mdAutoComplete 本質(zhì)是 Input 的擴(kuò)展當(dāng)options為空時(shí)即使open為true也不會(huì)展示下拉菜單避免用戶誤以為組件不可輸入。這意味著filterOption只負(fù)責(zé)從已有 options 中過(guò)濾不會(huì)憑空生成選項(xiàng)若需要?jiǎng)討B(tài)生成補(bǔ)全建議應(yīng)配合onSearch在搜索時(shí)更新options見(jiàn)下節(jié)。五、組合進(jìn)階filterOption 與 onSearch 的職責(zé)邊界filterOption本地過(guò)濾與onSearch搜索回調(diào)是 AutoComplete 兩種互補(bǔ)的搜索機(jī)制理解其邊界可以避免常見(jiàn)誤區(qū)filterOption負(fù)責(zé)從現(xiàn)有 options 中篩純前端、同步執(zhí)行性能開(kāi)銷(xiāo)小適合選項(xiàng)集合固定或量級(jí)較小的場(chǎng)景onSearch負(fù)責(zé)去外部取數(shù)據(jù)每次輸入變化時(shí)觸發(fā)常用于服務(wù)端搜索或動(dòng)態(tài)生成選項(xiàng)此時(shí)通常將filterOption設(shè)為false交由數(shù)據(jù)源自行保證匹配性官方動(dòng)態(tài)補(bǔ)全示例 components/auto-complete/demo/basic.tsx 展示了標(biāo)準(zhǔn)做法在onSearch中根據(jù)輸入文本實(shí)時(shí)setOptions生成候選如郵箱補(bǔ)全xxxgmail.com。5.1 結(jié)合使用本地不區(qū)分大小寫(xiě) 動(dòng)態(tài)選項(xiàng)import React, { useState } from react; import { AutoComplete } from antd; import type { AutoCompleteProps } from antd; const App: React.FC () { const [options, setOptions] useStateAutoCompleteProps[options]([]); const handleSearch (value: string) { // 模擬服務(wù)端檢索僅當(dāng)輸入非空時(shí)才生成候選 setOptions( value ? [Burns Bay Road, Downing Street, Wall Street] .filter((item) item.toLowerCase().includes(value.toLowerCase())) .map((item) ({ value: item })) : [], ); }; return ( AutoComplete style{{ width: 200 }} options{options} onSearch{handleSearch} filterOption{false} // 匹配已由 onSearch 完成避免二次過(guò)濾 placeholdertry to type b / ); }; export default App;六、可驗(yàn)證性測(cè)試快照與運(yùn)行方式該示例已被倉(cāng)庫(kù)測(cè)試覆蓋可通過(guò)測(cè)試驗(yàn)證渲染結(jié)果快照 components/auto-complete/tests/snapshots/demo.test.tsx.snap 中記錄了renders components/auto-complete/demo/non-case-sensitive.tsx correctly用例斷言輸入框含try to type \b占位文本、攜帶ant-select-auto-complete 等類(lèi)名運(yùn)行倉(cāng)庫(kù)測(cè)試套件可執(zhí)行npm test對(duì)應(yīng) jest 配置見(jiàn) package.json單獨(dú)驗(yàn)證該演示可運(yùn)行npx jest components/auto-complete。七、小結(jié)本示例的工程啟示交互體驗(yàn)英文場(chǎng)景下輸入大小寫(xiě)不敏感是剛需包含即命中非前綴匹配能顯著提升補(bǔ)全命中率實(shí)現(xiàn)成本僅需一行filterOption自定義函數(shù)無(wú)需改動(dòng)組件與數(shù)據(jù)源屬于零侵入增強(qiáng)最佳實(shí)踐小規(guī)模固定選項(xiàng)用filterOption本地過(guò)濾大規(guī)?;蚍?wù)端數(shù)據(jù)用onSearchfilterOption{false}兩者職責(zé)清晰、可組合使用這正是官方在 components/auto-complete/demo/non-case-sensitive.tsx 與 components/auto-complete/demo/basic.tsx 中分別演示的兩條路徑?!久赓M(fèi)下載鏈接】ant-designAn enterprise-class UI design language and React UI library項(xiàng)目地址: https://gitcode.com/gh_mirrors/ant/ant-design創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考