React && Antd的Table表头筛选自定义filterDropDown

一、问题描述

antd自带树形过滤有两个问题:

① 搜索仅仅加粗了筛选项,没有过滤其他项,若选项较多就不方便

② 确定按钮,只能在当前表内筛选,不可调用自己api接口,无法重新获取数据

二、解决思路

封装组件,挂载到filterDropDown属性下

三、编码

1、封装树形下拉组件

import {FilterDropdownProps} from 'antd/lib/table/interface';
import {
Button,
Divider,
Tree ,
Input,
} from 'antd';
import styles from './index.less';
import { Key } from 'react';
import { useState, useMemo} from 'react';
import { DataNode } from 'antd/lib/tree';


interface Props extends FilterDropdownProps{
  onSearch:(value:string[])=>void;
  multiple: boolean;
}
const TableTreeFilter:React.VFC<Props>=(prop)=>{
   const {
     setSelectedKeys,
     selectedKeys,
     filters,
     confirm,
     clearFilters,
     multiple
   } = props;
   const [treeData,setTreeData] = useState<DataNode[]>([]);
   const [treelist, setTreeList] = useState<DataNode[]>([]);
   //初始化树
   useMemo(() =>{
     const loop = (data: DataNode[]): DataNode[] => {
       data.map((item) => {
          const title  = item.title;
          if(item.children) {
            return {
              title,
              key:item.key,
              children:loop(item.children),
              disabled: item.disabled ? true : false,
            };
          }
          return {
            title,
            key: item.key,
            disabled:item.disabled ? true : false,
          };
       });
       
     setTreeData(loop(filters));
     setTreeList(loop(filters));
   },[]);
   //多选选中节点
   const onCheck = (checkValues:Key[]) =>{
      setSelectedKeys(checkValues);
   }
   //单选选中节点
   const onSelect = (value:Key[]) =>{
      setSelectedKeys(value);
   }
   //重置清空选中
   const clear = () =>{
      setSelctedKeys([]);
      clearFilters;
   }
   //【确定】并关闭搜索树返回选中项到表内筛选
   const onOk = () =>{
     props.onSearch(slectedKeys as string[]);
     confirm();
   }
   //过滤树节点
   const filterTreeNodes = (
      treeNodes:DataNode[],
      search:string
   ):DataNode[] => {
      const isMatched = (treeNode: DataNode, search: string):boolean=>{
        return (
          treeNode?.title.includes(search) ||
          treeNode?.children?.some((node) => {
              return isMatched(node,search)
          })
        );   
      };
      return treeNodes
        .map((node) =>{
           if(isMatched(node, search)){
              return {
                ...node,
                children:node.children
                ? filterTreeNodes(node.children, search)
                : [],
              };
           } else {
              return [];
           }
        })
        .flat();
   };
   //在树内搜索过滤项
   const onTreeSearch = (e:any) =>{
      const { value } = e.target;
      const newTree = filterTreeNodes(treeList, value);
      setTreeData(newTree);
   }
   return (
    <div className={styles.filterContent}>
     <Input
       placeholder="请输入"
       style={{ width: 210, margin: 10}}
       onChange={onTreeSearch}
     />
     <Divider />
     <Tree
       className={{styles.tree}}
       defaultExpandALl
       showIcon
       checkable=(multiple]
       //@ts- ignore
       onCheck={onCheck}
       onSelect={onSelect}
       selectedKeys={selectedKeys}
       checkedKeys={selectedKeys}
       //@ts - ignore
       treeData={treeData}
      />
     <Divider />
    <div className={styles.footer}>
      <Button
         size="small"
         disabled={!selectedKeys?.length}
         onClick={clear}
         style={{float:"left"}}
       >  
       重置
      </Button>
      <Button
         type="primary"
         size="small"
         onClick={onOk}
         style={{float:"right"}}
       >  
       重置
      </Button>
    </div>
 </div>
 ); 
};

export default TableTreeFilter;

2、在table中调用


const TreeList:TreeNode[] = [
      {
        text: 'Joe',
        value: '0',
      },
      {
        text: 'Category 1',
        value: '1',
        children: [
          {
            text: 'Yellow',
            value: '11',
          },
          {
            text: 'Pink',
            value: '12',
          },
        ],
      },
    ]

const columns: ColumnsType<DataType> = [
    {
    title: 'Name',
    dataIndex: 'name',
    filters: TreeList,
    filterDropDown:(props)=>{
     /**props是antd自带的一些属性,详情可见官网*/
     <TableTreeFilter
         {...props}
         onSearch={(value)=>{
           console.log(value);
           /**此回调函数,返回的value就是选中值,可做为table的筛选条件*/
           /**可在此处调用api接口*/
         }}
         /**可由此参数设置树结构为单选或者多选*/
         multiple={false}
      />
   },
   width: 120,
  },
]
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值