树选择中父区域控制子区域而子区域不控制父区域【TreeSelect】

该代码示例展示了一个React组件,利用AntDesign的TreeSelect组件处理多级区域选择。组件通过递归方法处理后端返回的数据,设置节点的title,key和value属性,并在选中节点时更新状态,实现全选和去重功能。同时,它支持清空选择、展示搜索、显示复选框并控制父子节点的选中策略。
摘要由CSDN通过智能技术生成
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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值