跳到主要内容

Select

用于从列表中选择单个或多个值的下拉选择器。

来源:antd 重新导出,并增加了 VEF Hook 增强。完整文档:Ant Design Select

何时使用

  • 选项内容较复杂时(例如包含图标或说明文字)。
  • 选项数量较多,需要筛选时。
  • 当选项少于 5 个时,请使用 Radio

基础用法

import { Select } from '@vef-framework-react/components';

const options = [
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'tom', label: 'Tom' },
];

export default function Demo() {
return (
<Select
style={{ width: 200 }}
placeholder="Select a person"
options={options}
onChange={(value) => console.log(value)}
/>
);
}

多选

import { Select } from '@vef-framework-react/components';

export default function Demo() {
return (
<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="Select multiple"
options={[
{ value: 'a', label: 'Option A' },
{ value: 'b', label: 'Option B' },
{ value: 'c', label: 'Option C' },
]}
/>
);
}

可搜索

import { Select } from '@vef-framework-react/components';

export default function Demo() {
return (
<Select
showSearch
style={{ width: 200 }}
placeholder="Search to select"
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={[
{ value: '1', label: 'Beijing' },
{ value: '2', label: 'Shanghai' },
{ value: '3', label: 'Guangzhou' },
]}
/>
);
}

VEF 增强:useDataOptionsSelect

VEF 提供了 useDataOptionsSelect,用于从异步数据源加载选项,内置了加载状态、拼音搜索支持和缓存能力。数据获取相关的选项统一嵌套在 queryOptions 中(与 TanStack Query 的 useQuery 接受的形状相同),useDataOptionsSelect 自身的选项与其平级。

import { Select, useDataOptionsSelect } from '@vef-framework-react/components';

async function fetchCities() {
const res = await fetch('/api/cities');
return res.json(); // returns DataOption[]
}

export default function Demo() {
const selectProps = useDataOptionsSelect({
queryOptions: {
queryKey: ['cities'],
queryFn: fetchCities,
},
filterable: true, // enables pinyin/text filtering
});

return <Select style={{ width: 200 }} {...selectProps} />;
}

useDataOptionsSelect 选项

选项类型默认值说明
queryOptionsUseQueryOptions<TQueryFnData[], TData[], TParams>必填TanStack Query 选项(queryKeyqueryFnuseQuery 的其余选项)
filterablebooleanfalse启用客户端文本/拼音过滤
onFetch(data: TData[]) => void数据获取完成后的回调
labelKeystring | (item: TData) => string"label"选项 label 的字段映射
valueKeystring | (item: TData) => Key"value"选项 value 的字段映射
disabledKeystring | (item: TData) => boolean | undefined"disabled"禁用状态的字段映射
descriptionKeystring | (item: TData) => string | undefined"description"选项说明文字的字段映射
childrenKeystring | (item: TData) => TData[] | undefined"children"嵌套子选项的字段映射(会递归转换)

每个 *Key 选项都可以是字符串路径(例如 "user.name")或提取函数。

该 Hook 返回的 SelectProps 可以直接展开到 <Select> 上。

VEF 增强:useCodeSetOptionsSelect

对于以码集为数据源的选项,useCodeSetOptionsSelect 封装了 useCodeSetQuery,为每个别名返回可直接展开的 SelectProps

import { Select, useCodeSetOptionsSelect } from '@vef-framework-react/components';

export default function Demo() {
const { gender, status } = useCodeSetOptionsSelect({
gender: 'common.gender',
status: { key: 'common.status', filterable: true },
});

return (
<>
<Select style={{ width: 200 }} {...gender} />
<Select style={{ width: 200 }} {...status} />
</>
);
}

所有别名会在一次批量码集查询中获取。背后的查询与应用上下文接线参见码集

useCodeSetOptionsSelect 签名

function useCodeSetOptionsSelect<const T extends CodeSetAliasMap>(
keys: T,
options?: UseCodeSetOptionsSelectOptions
): UseCodeSetOptionsSelectResult<T>;

keysCodeSetAliasMap,必填)把每个别名映射为一个 CodeSetKeyValue——码集键字符串,或一个 CodeSetKeyConfig 对象:

字段类型默认值说明
keyCodeSetKey必填码集键(通过 Register 增强获得类型约束,否则为 string
filterablebooleanHook 级别的 filterable按别名覆盖搜索过滤开关

optionsUseCodeSetOptionsSelectOptions,可选):

选项类型默认值说明
filterablebooleanfalse每个 select 是否启用搜索;带有自身 filterable 配置的别名优先于该默认值

返回值UseCodeSetOptionsSelectResult<T> = Record<keyof T, SelectProps<Key, DataOptionWithPinyin<DataOption>>>)——每个别名对应一个 SelectProps 对象,各自携带:

字段说明
optionsDataOptionWithPinyin<DataOption>[]码集条目(含嵌套 children),每一项都为 labeldescription 预计算了拼音
loadingboolean批量码集查询进行中时为 true
fieldNames{ label, value, options: 'children', groupLabel: 'label' }DataOption 的形状映射到 select 上
maxTagCount'responsive'多选模式下折叠超出的标签
listHeight280下拉列表高度
notFoundContent获取期间为 Loader初次获取期间显示加载器而非"暂无数据"
showSearchboolean该别名最终解析出的 filterable 标志
filterOption(input, option) => boolean匹配 label / description、其完整拼音及拼音首字母(仅在可过滤时设置)

API

PropTypeDefault说明
valuestring | string[]选中值(受控)
defaultValuestring | string[]初始值(非受控)
optionsSelectOption[]选项列表
mode'multiple' | 'tags'多选模式
placeholderstring占位文本
disabledbooleanfalse禁用选择器
loadingbooleanfalse显示加载状态
showSearchbooleanfalse启用搜索
allowClearbooleanfalse显示清除按钮
filterOptionboolean | functiontrue筛选函数
size'large' | 'medium' | 'small''medium'选择器尺寸('middle''medium' 的废弃别名)
status'error' | 'warning'校验状态
variant'outlined' | 'filled' | 'borderless''outlined'视觉变体
onChange(value, option) => void变化回调函数
onSearch(value: string) => void搜索回调函数
onClear() => void清除回调函数

最佳实践

  • 对于远程数据,使用 useDataOptionsSelect 可以避免手动管理加载状态。
  • 对于非必填字段,设置 allowClear
  • 在表单中使用时,请使用 Form 字段组件,它已与 VEF 表单系统集成:
<form.AppField name="city">
{(field) => <field.Select label="City" options={options} />}
</form.AppField>