Antd之使用React hooks设置表头字段可筛选


下面是antd 提供的表头筛选网站
https://preview.pro.ant.design/list/table-list?navTheme=light&primaryColor=%231890ff&layout=mix&fixSiderbar=true&title=Ant+Design+Pro
形式如下:
点击表格右上角的设置就可以实现表头字段的筛选
在这里插入图片描述

一、通过popover实现下拉菜单组件

(1)基本前端样式

 <div>
   <Popover placement="bottomRight" trigger="click" content={contentArr}> //这个地方是多选框内容
     <Button type="link" className={styles['slect-button']}>
       <SettingOutlined />
     </Button>
   </Popover>
 </div>

(2)实现多选

const [checkAll, setCheckAll] = useState(true); //设置是否全选
const [indeterminate, setIndeterminate] = useState(true);//设置是否半选
const contentArr = (
   <>
     <div className={styles['check-all']}>
     //全选onchange
       <Checkbox onChange={handleOnchange} checked={checkAll} indeterminate={indeterminate}>
         全选
       </Checkbox>
     </div>
     <div className={styles['check-box']}>
       <Checkbox.Group
         options={arr} //这里的arr是传进来的columns
         className={styles['check-box__group']}
         onChange={onChildrenChange} //单选onchange
         value={value}
       />
     </div>
   </>
 );

(3)设置全选和半选

  const handleOnchange = useCallback(
    e => {
      if (e.target.checked) {
      //columns是接受的数据
        onChange(columns.map(item => item.key as string));
      } else {
        onChange([]);
      }
      setIndeterminate(false);
      setCheckAll(e.target.checked);
    },
    [setCheckAll, columns, onChange],
  );

  const onChildrenChange = useCallback(
    values => {
      setIndeterminate(!!values.length && values.length < columns.length);
      setCheckAll(values.length === columns.length);
      onChange(values);
    },
    [columns, onChange],
  );

(4)源代码

1. 组件代码

完整代码如下:

import { SettingOutlined } from '@ant-design/icons';
import { Button, Checkbox, Popover } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import React, { FC, useCallback, useState, useEffect } from 'react';
import { convertToData } from 'src/utils/covertToCheckData';
import styles from './select-menu.module.scss';

export interface Props {
  columns: ColumnsType;
  value: string[];
  onChange: (value: string[]) => void;
}

const SelectMenu: FC<Props> = ({ columns, value, onChange }): JSX.Element => {
  const [checkAll, setCheckAll] = useState(true);
  const [indeterminate, setIndeterminate] = useState(true);
  //对columns数据进行处理,需要转化成checkbox.group的数据
  const arr = convertToData(columns);
  const handleOnchange = useCallback(
    e => {
      if (e.target.checked) {
        onChange(columns.map(item => item.key as string));
      } else {
        onChange([]);
      }
      setIndeterminate(false);
      setCheckAll(e.target.checked);
    },
    [setCheckAll, columns, onChange],
  );

  const onChildrenChange = useCallback(
    values => {
      setIndeterminate(!!values.length && values.length < columns.length);
      setCheckAll(values.length === columns.length);
      onChange(values);
    },
    [columns, onChange],
  );
  useEffect(() => {
    setIndeterminate(!!value.length && value.length < columns.length);
  }, [value, columns]);
  const contentArr = (
    <>
      <div className={styles['check-all']}>
        <Checkbox onChange={handleOnchange} checked={checkAll} indeterminate={indeterminate}>
          全选
        </Checkbox>
      </div>
      <div className={styles['check-box']}>
        <Checkbox.Group
          options={arr}
          className={styles['check-box__group']}
          onChange={onChildrenChange}
          value={value}
        />
      </div>
    </>
  );

  return (
    <div>
      <Popover placement="bottomRight" trigger="click" content={contentArr}>
        <Button type="link" className={styles['slect-button']}>
          <SettingOutlined />
        </Button>
      </Popover>
    </div>
  );
};

export default SelectMenu;

2. scss代码如下:

.slect-button {
  color: #333;
  font-size: 16px;
  float: right;
}

.check-all {
  min-height: 32px;
  margin: 0;
  padding: 5px 1px;
  color: rgba(0, 0, 0, 0.85);
  font-weight: 500;
  border-bottom: 1px solid #f0f0f0;
}

.check-box {
  padding-top: 6px;
  padding-left: 10px;

  &__group {
    display: flex;
    flex-direction: column;
    line-height: 1.8;
  }
}

3. 转化columns的函数

export function convertToData(list: any[]) {
  list.forEach(item => {
    item.label = item.title;
    item.value = item.key;
  });
  return list;
}

4. 最终实现结果

在这里插入图片描述

二、页面组件基本使用

<div>
  <SelectMenu//组件调用
      columns={columns} //传入基本的columns
      onChange={selectMenuList.onchange}  //hooks参考第三点
      value={selectMenuList.colValue}//hooks参考第三点
    />
    <Table
      dataSource={list}
      rowKey="id"
      columns={selectMenuList.columnsData}//hooks参考第三点
      scroll={{ x: 1500, y: 1000 }}
      pagination={{
        pageSize,
        total,
        current: pageIndex,
        showSizeChanger: true,
        pageSizeOptions: ['10', '20', '30'],
      }}
      onChange={handlePaginationChange}
    />
</div>

三、hooks处理table columns数据

(1)hooks封装

因为前端页面肯定不是这一个页面使用,减少重复代码使用hooks进行配置:

import { ColumnsType } from 'antd/lib/table';
import { useCallback, useState } from 'react';

export const useSelectMenu = (columns: ColumnsType) => {
//这个是checkbox选中下的value,默认是全部
  const [colValue, setColValue] = useState<string[]>(columns.map(item => item.key as string));
  //这个是在所有的columns中过滤出选中的数据
  const columnsData = columns.filter(item => colValue.includes(item.key as string));
  //当change函数调用时set进去被选中的数据
  const onchange = useCallback(values => {
    setColValue(values);
  }, []);
  return {
    colValue,
    columnsData,
    onchange,
  };
};

(2)hooks 的使用

  const selectMenuList = useSelectMenu(columns);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值