react+antd实现表格封装,可动态控制列显示隐藏。

文章介绍了如何使用React和Antd库封装一个表格组件,该组件支持动态控制列的显示和隐藏,包括全选列的功能。提供了代码示例和Gitee仓库链接,便于读者理解和复用。此外,还涉及了npm安装和组件的使用方式。
摘要由CSDN通过智能技术生成

react+antd实现表格封装,可动态控制列显示隐藏。

升级版本

升级表格封装,把请求犯法都加进去了,后续无脑开发!!!

实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

git地址

https://gitee.com/jumping-little-stars/dynamic-colums-table.git

https://gitee.com/jumping-little-stars/dynamic-colums-table

npm 安装

cnpm i dynamic-tablelist-colums

代码讲解

import { Table, Pagination, Button, Dropdown, Checkbox, message } from 'antd';
import { useState, useEffect } from 'react';
import { PicRightOutlined } from '@ant-design/icons';

import './index.less';

const TableComponent = (props) => {
  const [open, setOpen] = useState(false); //动态控制列的下拉显隐
  const [items, setItems] = useState([]);//当前的下拉选择状态

  // 表格列表
  const [columns, setColumns] = useState(
    props.columns.map((item) => {
      return {
        ...item,
        align: 'center',
        ellipsis: {
          showTitle: false,
        },
      };
    }),
  );

  //控制列的初始值
  const [starCol, setStarCol] = useState(
    props.columns.map((item) => {
      return {
        ...item,
        check: true,
        align: 'center',
        ellipsis: {
          showTitle: false,
        },
      };
    }),
  );

  useEffect(() => {
    changItem(starCol);
  }, [props]);

//动态传入列时,更新
  useEffect(() => {
    if (props.columns || props.columns.length > 0) {
      setColumns(
        props.columns.map((item) => {
          return {
            ...item,
            align: 'center',
            ellipsis: {
              showTitle: false,
            },
          };
        }),
      );
      setStarCol(
        props.columns.map((item) => {
          return {
            ...item,
            check: true,
            align: 'center',
            ellipsis: {
              showTitle: false,
            },
          };
        }),
      );
    }
  }, [props.columns]);

  const serialNumber = (pageIndex, pageSize, index) => {
    return (pageIndex - 1) * pageSize + index;
  };

  // 控制显示列的操作
  const onClick = ({ key }) => {
    if (key == 'all') {
      const newDrop = starCol;
      newDrop.map((o, index) => {
        o.check = true;
      });
      changItem(starCol);
      setColumns(
        props.columns.map((item) => {
          return {
            ...item,
            check: true,
            align: 'center',
            ellipsis: {
              showTitle: false,
            },
          };
        }),
      );
    } else {
      const newDrop = starCol;
      newDrop.map((o, index) => {
        if (index == key) {
          o.check = !o.check;
        }
      });
      let newColumns = newDrop.filter((o) => o.check);
      if (newColumns.length == 0) {
        message.warning('请至少选择一列');
      } else {
        setStarCol(newDrop);
        changItem(newDrop);
        setColumns(newColumns); //列状态
      }
    }
  };

  // 列的选中状态改变
  const changItem = (data) => {
    let opitems = data.map((item, index) => {
      return {
        key: index,
        label: <Checkbox checked={item.check}>{item.title}</Checkbox>,
      };
    });
    opitems.unshift(
      {
        key: 'all',
        label: <Button>{'全选列'}</Button>,
      },
      {
        type: 'divider',
      },
    );
    setItems(opitems); //当前的下拉状态
  };
  // 控制分页索引对应的数据源
  const dataSource = props.dataSource?.map((item, index) => {
    return {
      index: serialNumber(props.defaultCurrent, props.size, index + 1),
      ...item,
    };
  });

  return (
    <div className="table">
      <Dropdown
        menu={{
          items,
          onClick,
        }}
        overlayClassName="drop"
        trigger={['click']}
        onOpenChange={() => setOpen(!open)}
        open={open}
        arrow
        placement="bottomRight"
      >
        <a onClick={(e) => e.preventDefault()}>
          <Button icon={<PicRightOutlined />} title="显示/隐藏列"></Button>
        </a>
      </Dropdown>
      <Table
        bordered
        columns={columns}
        rowSelection={props?.rowSelection}
        dataSource={dataSource}
        rowKey={(item) => item.id}
        pagination={false}
        className="insiadeTable"
        scroll={{
          y: 450,
          ...props?.scroll,
        }}
        onRow={props?.onRow}
        rowClassName={props?.rowClassName}
        summary={props?.summary}
      />
      <div className="pagination">
        {props.total ? (
          <Pagination
            showQuickJumper
            defaultCurrent={props.defaultCurrent}
            total={props.total}
            showTotal={(total) => `${total}`}
            size={props.size}
            onChange={props.paginationChange}
            pageSizeOptions={[10, 50, 100, 500]}
          />
        ) : (
          ''
        )}
      </div>
    </div>
  );
};

export default TableComponent;


页面使用

 <TableComponent
        className="list"
        columns={columns}
        dataSource={roleList}
        scroll={{
          x: 1600,
        }}
        total={listTotal}
        size={listSize}
        defaultCurrent={current}
        paginationChange={paginationChange}
      />
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值