antd react Table组件封装(含分页)

组件效果

1. table组件封装

import { ReactNode, useImperativeHandle } from 'react';
import { useEffect, useState } from 'react';
import React from 'react';
import { Table, Pagination, TablePaginationConfig } from 'antd';
import SearchFilter from '@/components/SearchFilter';
import './index.less';

export type event = {
  fetchData: (data?: any) => void;
};

interface SearchFilterProps {
  /**
   * 每列
   * */
  columns: any;
  /**
   * 请求数据
   * */
  /**
   * 左边节点
   * */
  prefix?: ReactNode;
  /**
   * 右边节点
   * */
  suffix?: ReactNode;
  /**
   * 右边节点
   * */
  filterSearch?: ReactNode;

  /**
   * 请求api 函数
   * */
  fetchTableData: unknown | any;

  /**
   * rowKey
   * */
  rowKey?: string;

  scroll?: any;

  tablerefs?: any;

  query?: any;

  pagination?: boolean;
}

const FromTable: React.FC<SearchFilterProps> = (props: SearchFilterProps) => {
  const {
    columns,
    rowKey,
    prefix,
    suffix,
    filterSearch,
    fetchTableData,
    tablerefs,
    query,
    pagination,
    scroll,
  } = props;
  /**
   * 数据集合
   * */
  const [dataSource, setdataSource] = useState<any>([]);
  /**
   * 总条数据
   * */
  const [totalPage, settotalPage] = useState<number>(0);
  /**
   * 页大小
   * */
  const [pageSize, setpageSize] = useState<number>(10);
  /**
   * 当前
   * */
  const [current, setcurrent] = useState<number>(1);
  /**
   * 加载loading
   * */
  const [loading, setloading] = useState<boolean>(false);
  /**
   * 保留参数
   * */
  const [queryData, setqueryData] = useState<any>({});
  /**
   * 请求数据函数体
   * */
  const getdataSource = async (data?: any) => {
    setloading(true);
    const res = await fetchTableData({
      pageSize,
      currentPage: current,
      ...query,
      ...data,
    });
    if (res.code === 200) {
      if (rowKey === 'index') {
        const list = res.data.map((item: any, index: number) => {
          return {
            ...item,
            index: index + 1,
          };
        });
        console.log(list, 'list');
        setdataSource(list);
      } else {
        setdataSource(res.data);
      }

      settotalPage(res.dataTotal);
      setTimeout(() => {
        setloading(false);
      }, 1000);
    } else {
      setTimeout(() => {
        setloading(false);
      }, 1000);
    }
    console.log(res);
  };
  useEffect(() => {
    getdataSource();
  }, []);

  useImperativeHandle(tablerefs, () => ({
    fetchData: (data: any) => {
      setqueryData(data);
      setcurrent(data.currentPage);
      getdataSource(data);
    },
  }));
  const paginationProps: TablePaginationConfig = {
    showSizeChanger: true,
    showQuickJumper: true,
    size: 'default',
    current: current,
    pageSize: pageSize,
    pageSizeOptions: ['10', '20', '50', '100'],
    total: totalPage,
    showTotal: () => `共 ${totalPage} 条`,
    // ...pagination,
  };
  return (
    <div className="FromTable">
      <SearchFilter prefix={prefix} suffix={suffix} filterSearch={filterSearch} />
      <Table
        scroll={scroll}
        rowKey={rowKey}
        columns={columns}
        loading={loading}
        dataSource={dataSource}
        pagination={false}
      />
      {pagination && (
        <div className="pagination">
          <Pagination
            {...paginationProps}
            // eslint-disable-next-line @typescript-eslint/no-shadow
            onChange={(page: number, pageSize: number) => {
              console.log(page, pageSize);
              setcurrent(page);
              setpageSize(pageSize);
              getdataSource({ ...queryData, currentPage: page, pageSize: pageSize });
            }}
          />
        </div>
      )}
    </div>
  );
};
FromTable.defaultProps = {
  rowKey: 'id',
  pagination: true,
  scroll: { x: 1000 },
};

export default FromTable;

2. 父组件调用示例

import React, { useState, useRef } from 'react';
import { Button, Card, Image, Input, Space } from 'antd';
import FromTable from '@/components/Table';
import { getPage } from '@/services';
import { imgResize } from '@/utils/imgSize';
import { Link } from 'umi';

const Short: React.FC<any> = () => {
  const tablerefs = useRef<any>({});
  const [params, setParams] = useState({
    keyword: '',
    currentPage: 1,
  });

  const columns = [
    {
      title: '序号',
      dataIndex: 'id',
      align: 'center',
      fixed: 'left',
      width: 38,
      render: (_: any, text: any, index: number) => {
        return <div>{index + 1}</div>;
      },
    },
    {
      title: '昵称',
      dataIndex: 'name',
      align: 'center',
      width: 100
    },
    {
      title: '头像',
      dataIndex: 'poster',
      align: 'center',
      width: 100,
      render: (text: any) => {
        return (
          <Image
            className="avatarImg"
            width={50}
            height={50}
            src={text + imgResize.RESIZE100}
            preview={{ src: text }}
          />
        );
      },
    },
    {
      title: '浏览人数',
      dataIndex: 'videoTotalPeopleNum',
      align: 'center',
      width: 100,
      render: (text: any) => {
        return <>{text || 0}</>;
      },
    },
    {
      title: '操作',
      dataIndex: 'operation',
      align: 'center',
      fixed: 'right',
      width: 100,
      render: (text: any, row: any) => {
        return (
          <Button type="link">
            <Link>
              详情
            </Link>
          </Button>
        );
      },
    },
  ];
  /**
   * 提交查询
   * */
  const submit = () => {
    tablerefs.current.fetchData(params);
  };
  /**
   * 输入的值
   * */
  const onkeyword = (evt: any) => {
    setParams({ ...params, keyword: evt.target.value });
  };
  const filterSearch = () => (
    <>
      <Space>
        <Input
          placeholder="请输入昵称"
          value={params.keyword}
          style={{ width: 200 }}
          onInput={onkeyword}
        />
        <Button type="primary" onClick={submit}>
          查询
        </Button>
      </Space>
    </>
  );
  return (
    <Card>
      <FromTable
        tablerefs={tablerefs}
        prefix={filterSearch()}
        filterSearch={null}
        scroll={{ x: 1500, y: 500 }}
        columns={columns}
        fetchTableData={getPage}
      />
    </Card>
  );
};

export default Short;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值