index.jsx 3.88 KB
Newer Older
张烨's avatar
张烨 committed
1 2 3 4
import React, { useEffect, useState } from 'react';
// import OperationBar from './OperationBar'
import { Table } from 'antd';
import { Resizable } from 'react-resizable';
张烨's avatar
张烨 committed
5
import SearchBar from './SearchBar';
张烨's avatar
张烨 committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
import styles from './baseTable.less';
const ResizableTitle = props => {
  const { onResize, width, ...restProps } = props;

  if (!width) {
    return <th {...restProps} />;
  }

  return (
    <Resizable
      width={width}
      height={0}
      handle={
        <span
          className="react-resizable-handle"
          onClick={e => {
            e.stopPropagation();
          }}
        />
      }
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};

// 表格头变形的hook
张烨's avatar
张烨 committed
35 36
const useResizableClumns = clumns => {
  const [clmns, setClmns] = useState(clumns);
张烨's avatar
张烨 committed
37
  if (!clumns) return null;
张烨's avatar
张烨 committed
38 39
  const handleResize = index => (e, { size }) => {
    const nextClmns = [...clmns];
张烨's avatar
张烨 committed
40 41
    nextClmns[index] = {
      ...nextClmns[index],
张烨's avatar
张烨 committed
42 43 44 45
      width: size.width,
    };
    setClmns(nextClmns);
  };
张烨's avatar
张烨 committed
46 47 48 49 50 51 52
  return clmns.map((col, index) => ({
    ...col,
    onHeaderCell: column => ({
      width: column.width,
      onResize: handleResize(index),
    }),
  }));
张烨's avatar
张烨 committed
53
};
张烨's avatar
张烨 committed
54 55 56 57 58 59

// 渲染列表组件
const renderComponents = (componentOption = {}) => {
  const defaultComponents = {
    header: {
      cell: ResizableTitle,
张烨's avatar
张烨 committed
60 61
    },
  };
张烨's avatar
张烨 committed
62 63 64
  return {
    ...defaultComponents,
    ...componentOption,
张烨's avatar
张烨 committed
65 66
  };
};
张烨's avatar
张烨 committed
67 68

// 过滤列表数据
69 70 71 72 73 74 75 76 77 78 79 80
const filterData = (datas, searches, searchVal) =>{
  return datas.filter( data =>{
    return  searches.every(item =>{
        if(searchVal[item.dataIndex]){
          return  data[item.dataIndex].includes(searchVal[item.dataIndex])
        }else{
          return true
        }
      })
    })
}

张烨's avatar
张烨 committed
81

张烨's avatar
张烨 committed
82 83
const BaseTable = props => {
  const {
84
    searchBar, // 筛选栏属性{items: [{filter: () => boolean, key, dataIndex, label, type, initialValue?, options?}]}
张烨's avatar
张烨 committed
85 86 87 88 89 90 91
    operation, // 操作栏属性,可选
    dataSource, // 数据源,可选
    columns, // 列,必填
    resizable, // 列宽是否可调整,可选
    components, // 自定义table渲染,同antd/table, 可选
    onRequest, // 请求数据接口,非必须,需返回Promise<{data, pagenation}>,可选,与dataSource冲突,优先onRequest
    onSearchCommit, // 筛选回调, 可选
张烨's avatar
张烨 committed
92
    // onPageChange, // 翻页时回调
张烨's avatar
张烨 committed
93 94 95 96 97 98 99 100
    ...restProps
  } = props;
  let resizableClumns = useResizableClumns(columns);
  resizableClumns = resizable ? resizableClumns : columns;
  const [dataList, setDataList] = useState(dataSource || []);
  const [pagenation, setPageNation] = useState({});
  const [loading, setLoading] = useState(false);
  const [seachVal, setSearchVal] = useState({});
张烨's avatar
张烨 committed
101 102

  const fetch = (page, search) => {
张烨's avatar
张烨 committed
103
    search = search || seachVal;
张烨's avatar
张烨 committed
104
    if (onRequest) {
张烨's avatar
张烨 committed
105
      setLoading(true);
张烨's avatar
张烨 committed
106
      onRequest(page || pagenation, search).then(res => {
张烨's avatar
张烨 committed
107 108
        console.log(res);
        setDataList(
109
          searchBar ? filterData(res.data, searchBar.items, search) : res.data,
张烨's avatar
张烨 committed
110 111 112 113
        );
        setPageNation(res.pagenation);
        setLoading(false);
      });
张烨's avatar
张烨 committed
114
    } else {
张烨's avatar
张烨 committed
115
      setDataList(
116
        searchBar ? filterData(dataSource, searchBar.items, search) : dataSource,
张烨's avatar
张烨 committed
117 118
      );
      setPageNation(page);
张烨's avatar
张烨 committed
119
    }
张烨's avatar
张烨 committed
120
  };
张烨's avatar
张烨 committed
121

张烨's avatar
张烨 committed
122 123 124
  const handleChange = page => {
    fetch(page);
  };
张烨's avatar
张烨 committed
125

张烨's avatar
张烨 committed
126
  const handleSearchCommit = value => {
127
    fetch(pagenation,value)
张烨's avatar
张烨 committed
128
  };
张烨's avatar
张烨 committed
129 130

  useEffect(() => {
张烨's avatar
张烨 committed
131 132 133
    fetch(pagenation);
  }, [dataSource]);
  return (
134 135
    <div className={styles.baseTable}>
      {searchBar?.items?.length > 0 && (
张烨's avatar
张烨 committed
136 137 138
        <SearchBar {...searchBar} onCommit={handleSearchCommit} />
      )}
      <Table
139
        className={styles.table}
张烨's avatar
张烨 committed
140 141 142 143 144 145 146 147 148 149
        dataSource={dataList}
        loading={loading}
        components={renderComponents(components)}
        columns={resizableClumns}
        onChange={handleChange}
        {...restProps}
      />
    </div>
  );
};
张烨's avatar
张烨 committed
150

张烨's avatar
张烨 committed
151
export default BaseTable;