feat(select): 支持排除和包含选项的过滤功能

- 在组件中新增 exclude 和 include 属性,支持对数据进行筛选
- 使用 useMemo 优化实际展示数据的计算逻辑
- 引入工具函数 getMatchedItems 和 getUnmatchedItems 进行数据过滤
- 修改回调函数和 options 渲染为基于过滤后的数据
- 通过 onGetData 返回过滤后的数据列表
2.0
LiuJiaNan 2026-08-11 14:57:48 +08:00
parent 7f1375c1d8
commit 309cbebafc
2 changed files with 27 additions and 6 deletions

View File

@ -21,6 +21,10 @@ export interface BasicSelectProps extends SelectProps {
onGetData?: (data: Record<string, any>[]) => void; onGetData?: (data: Record<string, any>[]) => void;
/** 自定义 label 的渲染函数 */ /** 自定义 label 的渲染函数 */
labelRender?: (item: Record<string, any>) => ReactNode; labelRender?: (item: Record<string, any>) => ReactNode;
/** 排除的项 */
exclude?: string[];
/** 包含的项 */
include?: string[];
} }
/** /**

View File

@ -1,5 +1,6 @@
import { Select } from "antd"; import { Select } from "antd";
import { useEffect } from "react"; import { useEffect, useMemo } from "react";
import { getMatchedItems, getUnmatchedItems } from "../../../utils/index.js";
/** /**
* 基础下拉组件 * 基础下拉组件
@ -15,9 +16,25 @@ function BasicSelect(props) {
nameKey = "name", nameKey = "name",
idKey = "id", idKey = "id",
labelRender, labelRender,
exclude = [],
include = [],
...restProps ...restProps
} = props; } = props;
const actualData = useMemo(() => {
let result = data;
if (exclude.length > 0) {
result = getUnmatchedItems({ list: result, value: exclude, idKey });
}
if (include.length > 0) {
result = getMatchedItems({ list: result, value: include, idKey });
}
return result;
}, [data, exclude, include, idKey]);
const handleChange = (event, option) => { const handleChange = (event, option) => {
if (onGetLabel || onGetOption) { if (onGetLabel || onGetOption) {
if (Array.isArray(event)) { if (Array.isArray(event)) {
@ -25,7 +42,7 @@ function BasicSelect(props) {
const findItems = []; const findItems = [];
const names = []; const names = [];
event.forEach((item) => { event.forEach((item) => {
const findItem = data.find(dataItem => dataItem[idKey] === item); const findItem = actualData.find(dataItem => dataItem[idKey] === item);
if (findItem) { if (findItem) {
findItems.push(findItem); findItems.push(findItem);
names.push(findItem[nameKey]); names.push(findItem[nameKey]);
@ -41,7 +58,7 @@ function BasicSelect(props) {
} }
else { else {
if (event) { if (event) {
const findItem = data.find(item => item[idKey] === event); const findItem = actualData.find(item => item[idKey] === event);
onGetLabel?.(findItem[nameKey]); onGetLabel?.(findItem[nameKey]);
onGetOption?.(findItem); onGetOption?.(findItem);
} }
@ -55,8 +72,8 @@ function BasicSelect(props) {
}; };
useEffect(() => { useEffect(() => {
onGetData?.(data); onGetData?.(actualData);
}, [data]); }, [actualData]);
return ( return (
<Select <Select
@ -64,7 +81,7 @@ function BasicSelect(props) {
showSearch={{ optionFilterProp: "children" }} showSearch={{ optionFilterProp: "children" }}
allowClear allowClear
onChange={handleChange} onChange={handleChange}
options={data.map(item => ({ options={actualData.map(item => ({
value: item[idKey], value: item[idKey],
label: labelRender ? labelRender(item) : item[nameKey], label: labelRender ? labelRender(item) : item[nameKey],
}))} }))}