refactor: CustomSelect component update

This commit is contained in:
zhaoying
2026-01-20 10:15:12 +08:00
parent 2d90b0c752
commit 3ced895c9c

View File

@@ -1,10 +1,13 @@
import { useEffect, useState, type FC, type Key } from 'react'; import { useEffect, useState, type FC, type Key } from 'react';
import { Select } from 'antd' import { Select } from 'antd';
import type { SelectProps, DefaultOptionType } from 'antd/es/select' import type { SelectProps, DefaultOptionType } from 'antd/es/select';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { request } from '@/utils/request'; import { request } from '@/utils/request';
// 定义API响应类型 interface OptionType {
[key: string]: Key | string | number;
}
interface ApiResponse<T> { interface ApiResponse<T> {
items?: T[]; items?: T[];
} }
@@ -20,19 +23,16 @@ interface CustomSelectProps extends Omit<SelectProps, 'filterOption'> {
format?: (items: OptionType[]) => OptionType[]; format?: (items: OptionType[]) => OptionType[];
showSearch?: boolean; showSearch?: boolean;
optionFilterProp?: string; optionFilterProp?: string;
// 其他SelectProps属性
onChange?: SelectProps<Key, DefaultOptionType>['onChange'];
value?: SelectProps<Key, DefaultOptionType>['value'];
disabled?: boolean;
style?: React.CSSProperties;
className?: string;
filterOption?: (inputValue: string, option?: DefaultOptionType) => boolean; filterOption?: (inputValue: string, option?: DefaultOptionType) => boolean;
} }
interface OptionType {
[key: string]: Key | string | number; const defaultFilterOption = (inputValue: string, option?: DefaultOptionType): boolean => {
} if (!option || !inputValue) return true;
const label = String(option.children || option.label || '');
return label.toLowerCase().includes(inputValue.toLowerCase());
};
const CustomSelect: FC<CustomSelectProps> = ({ const CustomSelect: FC<CustomSelectProps> = ({
onChange,
url, url,
params, params,
valueKey = 'value', valueKey = 'value',
@@ -42,42 +42,37 @@ const CustomSelect: FC<CustomSelectProps> = ({
allTitle, allTitle,
format, format,
showSearch = false, showSearch = false,
optionFilterProp = 'label',
filterOption, filterOption,
...props ...props
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [options, setOptions] = useState<OptionType[]>([]); const [options, setOptions] = useState<OptionType[]>([]);
// 默认模糊搜索函数
const defaultFilterOption = (inputValue: string, option?: DefaultOptionType) => {
if (!option || !inputValue) return true;
const label = String(option.children || option.label || '');
return label.toLowerCase().includes(inputValue.toLowerCase());
};
// 组件挂载时获取初始数据
useEffect(() => { useEffect(() => {
request.get<ApiResponse<OptionType>>(url, params).then((res) => { request.get<ApiResponse<OptionType>>(url, params).then((res) => {
const data = res; const data = Array.isArray(res) ? res : res?.items || [];
setOptions(Array.isArray(data) ? data || [] : Array.isArray(data?.items) ? data.items || [] : []); setOptions(data);
}); });
}, []); }, [url, params]);
const displayOptions = format ? format(options) : options;
return ( return (
<Select <Select
placeholder={placeholder ? placeholder : t('common.select')} placeholder={placeholder || t('common.select')}
onChange={onChange}
defaultValue={hasAll ? null : undefined} defaultValue={hasAll ? null : undefined}
showSearch={showSearch} showSearch={showSearch}
filterOption={filterOption || defaultFilterOption} filterOption={filterOption || defaultFilterOption}
{...props} {...props}
> >
{hasAll && (<Select.Option>{allTitle || t('common.all')}</Select.Option>)} {hasAll && <Select.Option value={null}>{allTitle || t('common.all')}</Select.Option>}
{(format ? format(options) : options)?.map(option => ( {displayOptions.map((option) => (
<Select.Option key={option[valueKey]} value={option[valueKey]}> <Select.Option key={option[valueKey]} value={option[valueKey]}>
{String(option[labelKey])} {String(option[labelKey])}
</Select.Option> </Select.Option>
))} ))}
</Select> </Select>
); );
} };
export default CustomSelect; export default CustomSelect;