import React, { useEffect, useState } from 'react'; // import OperationBar from './OperationBar' import { Table } from 'antd'; import { Resizable } from 'react-resizable'; import SearchBar from './SearchBar'; 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 const useResizableClumns = clumns => { const [clmns, setClmns] = useState(clumns); if (!clumns) return null; const handleResize = index => (e, { size }) => { const nextClmns = [...clmns]; nextClmns[index] = { ...nextClmns[index], width: size.width, }; setClmns(nextClmns); }; return clmns.map((col, index) => ({ ...col, onHeaderCell: column => ({ width: column.width, onResize: handleResize(index), }), })); }; // 渲染列表组件 const renderComponents = (componentOption = {}) => { const defaultComponents = { header: { cell: ResizableTitle, }, }; return { ...defaultComponents, ...componentOption, }; }; // 过滤列表数据 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 } }) }) } const BaseTable = props => { const { searchBar, // 筛选栏属性{items: [{filter: () => boolean, key, dataIndex, label, type, initialValue?, options?}]} operation, // 操作栏属性,可选 dataSource, // 数据源,可选 columns, // 列,必填 resizable, // 列宽是否可调整,可选 components, // 自定义table渲染,同antd/table, 可选 onRequest, // 请求数据接口,非必须,需返回Promise<{data, pagenation}>,可选,与dataSource冲突,优先onRequest onSearchCommit, // 筛选回调, 可选 // onPageChange, // 翻页时回调 ...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({}); const fetch = (page, search) => { search = search || seachVal; if (onRequest) { setLoading(true); onRequest(page || pagenation, search).then(res => { console.log(res); setDataList( searchBar ? filterData(res.data, searchBar.items, search) : res.data, ); setPageNation(res.pagenation); setLoading(false); }); } else { setDataList( searchBar ? filterData(dataSource, searchBar.items, search) : dataSource, ); setPageNation(page); } }; const handleChange = page => { fetch(page); }; const handleSearchCommit = value => { fetch(pagenation,value) }; useEffect(() => { fetch(pagenation); }, [dataSource]); return ( <div className={styles.baseTable}> {searchBar?.items?.length > 0 && ( <SearchBar {...searchBar} onCommit={handleSearchCommit} /> )} <Table className={styles.table} dataSource={dataList} loading={loading} components={renderComponents(components)} columns={resizableClumns} onChange={handleChange} {...restProps} /> </div> ); }; export default BaseTable;