import { TreeSelect } from 'antd';
import { difference } from 'lodash';
const { SHOW_ALL } = TreeSelect;
const Demo: React.FC<any> = () => {
// 区域列表 定义初始化
const [dataAreaList, setDataArea] = useState<any>();
// 选中区域
const [valueArea, setValueArea] = useState<any>();
// 使用递归方法,在children数组中添加value和title值
useUpdateEffect(() => {
const fn = (val: any[]) => {
val.forEach((item) => {
item.title = item.label;
item.key = item.id;
item.value = item.id;
if (item.children && item.children.length > 0) {
fn(item.children);
}
});
};
fn(dataArea); // 此参数为后端接口返回数据
setDataArea(dataArea);
}, [dataArea]);
// 递归将将带有 children 数组的多层级数据转化为一维数组
const flatten = (array: any) => {
return array.reduce((acc: any, item: any) => {
if (item.children && item.children.length) {
return [...acc, item, ...flatten(item.children)];
} else {
return [...acc, item];
}
}, []);
};
// 选中树节点时调用此函数
const handleChangeArea = (val: any, label: any, extra: any) => {
// 通过递归转化为一维数组
const list = flatten(dataAreaList);
// 变化val 与 list进行比较 id 相同的
const select = val.map((item: { value: string }) => list.find((e: any) => item.value == e.id));
// 通过筛选父区域 可以选择全部子区域
const uniqueParent = flatten(select);
const uniqueArr: any[] = [];
// 去重
uniqueParent.forEach((obj: { id: string }) => {
if (!uniqueArr.some((o) => o.id === obj.id)) {
uniqueArr.push(obj);
}
});
// 判断当前节点是否被选中
// 如果选中 显示的为它以及它的所有子区域,如果没有子区域,则显示他自己即可
// 如果取消选中 则取消它本身的选中状态,与父区域无关
if (extra.checked) {
setValueArea(uniqueArr);
setTotalArea(uniqueArr.length);
} else {
// 去重
const triggerValue = difference(val, extra.triggerValue);
setValueArea(triggerValue);
setTotalArea(triggerValue.length);
}
};
return (
<TreeSelect
allowClear // 允许清空
suffixIcon={<CaretDownOutlined />} // 文本框 右侧下拉图标
showArrow={true} // 如果是复选 显示icon 需要结合showArrow为true
treeData={dataAreaList} // 树数据
value={valueArea} // 选中树数据
onChange={handleChangeArea} // 改变事件
showSearch={false} // 是否显示搜索
treeCheckable={true} // 显示 Checkbox
treeCheckStrictly={true} // 父子节点完全受控
showCheckedStrategy={SHOW_ALL} // 显示所有选中节点,显示所有选中父节点,显示所有选中子节点
placeholder="请选择区域"
treeDefaultExpandAll // 默认展开所有树节点
getPopupContainer={() => refs.current} // 遇到菜单滚动定位问题,试试修改为滚动的区域
/> );
};
export default Demo;
树选择中父区域控制子区域而子区域不控制父区域【TreeSelect】
于 2023-05-19 14:24:39 首次发布
该代码示例展示了一个React组件,利用AntDesign的TreeSelect组件处理多级区域选择。组件通过递归方法处理后端返回的数据,设置节点的title,key和value属性,并在选中节点时更新状态,实现全选和去重功能。同时,它支持清空选择、展示搜索、显示复选框并控制父子节点的选中策略。
摘要由CSDN通过智能技术生成