antd-search-select
v1.0.2
Published
A searchable, paginated Select component for Ant Design with debounced remote search, scroll-to-load-more, and retrieve-on-mount support
Maintainers
Readme
中文 | English
安装
npm install antd-search-select在线演示
本地启动预览:
npm run preview依赖要求
| 依赖 | 版本 | |------|------| | react | >=18.2.0 | | react-dom | >=18.2.0 | | antd | >=6.0.0 |
使用示例
import { SearchSelect } from "antd-search-select";
import type { Identifiable } from "antd-search-select";
interface Customer extends Identifiable {
name: string;
number: string;
}
function CustomerSelect() {
const listRequest = async (search: string | undefined, page: number) => {
const res = await fetch(`/api/customers?search=${search ?? ""}&page=${page}`);
const data = await res.json();
return { items: data.items, totalCount: data.totalCount };
};
const retrieveRequest = async (id: number) => {
const res = await fetch(`/api/customers/${id}`);
return res.json();
};
return (
<SearchSelect<Customer>
listRequest={listRequest}
retrieveRequest={retrieveRequest}
labelRender={(item) => item.name}
placeholder="请选择客户"
/>
);
}Form 场景
import { Form } from "antd";
<Form.Item name="customer_id">
<SearchSelect<Customer>
listRequest={listRequest}
retrieveRequest={retrieveRequest}
labelRender={(item) => item.name}
placeholder="请选择客户"
/>
</Form.Item>完整功能示例
<SearchSelect<Customer>
listRequest={listRequest}
retrieveRequest={retrieveRequest}
labelRender={(item) => item.name}
value={selectedId}
onChange={(val) => setSelectedId(val)}
onSelect={(item) => console.log("选中:", item)}
searchFields={["name", "number"]}
allowClear
disabled={false}
size="middle"
placeholder="请选择客户"
/>API
SearchSelectProps 继承 SelectProps(排除了 showSearch、options、loading、onChange、onPopupScroll、value、filterOption、labelRender、mode、onSelect)。因此 antd Select 的标准属性(placeholder、allowClear、disabled、size、style、className 等)可直接使用。
SearchSelectProps
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| listRequest | (search: string \| undefined, page: number) => Promise<{ items: TItem[]; totalCount: number }> | — | 分页列表请求(必填)。search 为 undefined 时表示无搜索条件,应返回全部数据;page 从 1 开始 |
| retrieveRequest | (id: number) => Promise<TItem> | — | 根据 id 检索单条数据(必填)。用于 value 对应的条目不在已加载列表中的回显场景 |
| labelRender | (item: TItem) => ReactNode | — | 将原始数据转为选项的展示文本(必填) |
| value | number \| string \| null | — | 当前选中值。支持数字、数值字符串(表单回填场景)、null(视为空) |
| onChange | (value: number \| undefined) => void | — | 选中值变化回调,清空时传 undefined |
| onSelect | (item: TItem \| undefined) => void | — | 选项变化回调,返回原始数据对象;undefined 表示清空 |
| searchFields | (keyof TItem)[] | — | 客户端过滤字段列表。全量数据加载完毕后,搜索自动切换为本地过滤;不传或传空数组则始终走服务端过滤 |
Identifiable
所有数据项必须满足的泛型约束:
| 字段 | 类型 | 说明 |
|------|------|------|
| id | number | 主键,作为 Select 选项的 value |
导出类型
| 导出 | 说明 |
|------|------|
| SearchSelect | 搜索型 Select 组件 |
| SearchSelectProps | 组件 Props 类型 |
| Identifiable | 数据项基础接口 |
功能特性
- 分页加载:挂载时自动请求首页,滚动到底部加载更多
- 远程搜索 + 防抖:300ms 防抖后发起请求,避免频繁查询
- 全量后本地过滤:配置
searchFields且全局数据加载完毕后,搜索自动切换为客户端过滤,不再请求服务端 - 前缀细化:当前搜索词是上次请求关键词的前缀时,直接在已有超集数据中本地过滤
- 空搜索缓存:已确认无结果的搜索词不再重复请求
- 回显:
value对应的条目不在已加载列表中时,自动调用retrieveRequest获取 label - 最小 loading:200ms 阈值防止加载过快导致的闪烁
- 竞态防护:响应到达时校验搜索词是否变化,丢弃过期结果
本地开发
git clone https://github.com/Czw96/antd-search-select.git
cd antd-search-select
npm install
npm run dev # 监听构建
npm run build # 生产构建
npm run preview # 启动预览页面
npm run lint # 代码检查许可证
MIT © Czw96
