目录
react实现table可拖拽表头 安装依赖 resizableTitle / index.tsx drapTable.tsx 使用DragTable 组件 滚动条样式 效果
react实现table可拖拽表头
安装依赖
yarn add react- resizable
yarn add react- jss
resizableTitle / index.tsx
import { createUseStyles } from 'react-jss' ;
import { Resizable } from 'react-resizable' ;
const useResizableTitleStyles = createUseStyles ( {
resizableHandle : {
position : 'absolute' ,
right : '-5px' ,
bottom : 0 ,
zIndex : 1 ,
width : '10px' ,
height : '100%' ,
cursor : 'col-resize'
}
} ) ;
export const ResizableTitle = ( { onResize, width, isNotResizable, ... restProps } ) => {
const classes = useResizableTitleStyles ( ) ;
const stopPropagation = ( event ) => event. stopPropagation ( ) ;
console. log ( 'isNotResizable' , isNotResizable, width, 'restProps' , restProps) ;
if ( ! width || isNotResizable) { return ( < th { ... restProps} / > ) } ;
return (
< Resizable
width= { width}
height= { 0 }
handle= {
< span className= { classes. resizableHandle} onClick= { stopPropagation} / >
}
onResize= { onResize}
draggableOpts= { { enableUserSelectHack : false } }
>
< th { ... restProps} style= { { ... restProps?. style, userSelect : 'none' } } / >
< / Resizable>
) ;
} ;
drapTable.tsx
import type { TableProps } from 'antd' ;
import { Table } from 'antd' ;
import { useState, useMemo, useEffect, useCallback } from 'react' ;
import type { ColumnType } from 'antd/lib/table' ;
import { ResizableTitle } from './resizableTitle/index' ;
import { createUseStyles } from 'react-jss' ;
interface TableStylesProps {
paddingVertical? : number;
paddingHorizontal? : number;
}
const useTableStyles = createUseStyles ( {
base_table_com : {
'& .ant-table-thead > tr > th, & .ant-table-tbody > tr > td, & .ant-table tfoot > tr > th, & .ant-table tfoot > tr > td' :
{
padding : ( cProps : TableStylesProps) =>
` ${ cProps. paddingVertical ?? 10 } px ${
cProps. paddingHorizontal ?? 12
} px ` ,
} ,
} ,
} ) ;
export const DragTable = < RecordType extends Record < string, any> = any> (
props : ICommonTableProps< RecordType> ,
) => {
const {
showTotalNum = true ,
pagination,
hidePagination,
paddingVertical,
paddingHorizontal,
} = props;
const [ tablePagination, setTablePagination] = useState< any> ( pagination) ;
const classes = useTableStyles ( { paddingVertical, paddingHorizontal } ) ;
const { columns } = props;
const [ rescolumns, setResColumns] = useState< ColumnType< any> [ ] > (
columns. filter ( ( column ) => ! column. hide) || [ ] ,
) ;
const handleResize = useCallback (
( index ) => {
return ( txt : any, Resize : any) => {
const temp = [ ... rescolumns] ;
temp[ index] = { ... temp[ index] , width : Resize. size. width } ;
setResColumns ( temp) ;
} ;
} ,
[ rescolumns] ,
) ;
const columnsMap : any[ ] = useMemo ( ( ) => {
return (
rescolumns?. map ( ( column : any, index) => {
return {
... column,
onHeaderCell : ( col : any) => ( {
width : col. width,
onResize : handleResize ( index) ,
isNotResizable : col. isNotResizable
} ) ,
} ;
} ) || [ ]
) ;
} , [ rescolumns, handleResize] ) ;
useEffect ( ( ) => {
const showTotal = {
showTotal : ( total : number, range : number[ ] ) => {
if ( showTotalNum) {
return ` 共{ ${ props. pagination ? props. pagination?. total : 0 } }条结果 ` ;
} else {
return '' ;
}
} ,
} ;
if ( ! hidePagination) {
setTablePagination ( Object. assign ( { } , pagination ?? { } , showTotal) ) ;
} else {
setTablePagination ( false ) ;
}
} , [ hidePagination, pagination, props. pagination, showTotalNum] ) ;
return (
< Table
{ ... props}
columns= { columnsMap}
pagination= { tablePagination}
components= { { header : { cell : ResizableTitle } } }
className= { classes. base_table_com}
/ >
) ;
} ;
interface CommonColumn < T > extends ColumnType < T > {
hide? : boolean;
}
export interface ICommonTableProps < RecordType> extends TableProps < RecordType> {
showTotalNum? : boolean;
hidePagination? : boolean;
columns : CommonColumn< RecordType> [ ] ;
paddingVertical? : number;
paddingHorizontal? : number;
}
使用DragTable 组件
import { createUseStyles } from 'react-jss' ;
import { useEffect, useMemo, useState, useRef } from 'react' ;
import { DragTable } from './drapTable' ;
import { Space } from "antd"
const TablePage = ( ) => {
const columns = [
{
title : '操作' ,
width : 60 ,
isNotResizable : true ,
render : ( _, record ) => (
< Space size= "middle" >
< a> 删除< / a>
< / Space>
) ,
} ,
{
title : '编码' ,
dataIndex : 'code' ,
width : 100 ,
} ,
{
title : '名称' ,
width : 100 ,
dataIndex : 'name' ,
} ,
{
title : '测试' ,
dataIndex : 'test' ,
width : 400 ,
} ,
{
title : '描述' ,
dataIndex : 'des' ,
width : 400 ,
} ,
] ;
const dataSource = [
{ id : 1 , code : '001' , name : '我是name1' , test : '测试一下1' , des : '描述一下' } ,
{ id : 2 , code : '002' , name : '我是name2' , test : '测试一下2' , des : '描述一下2' } ,
{ id : 3 , code : '003' , name : '我是name3' , test : '测试一下3' , des : '描述一下3' } ,
{ id : 4 , code : '004' , name : '我是name4' , test : '测试一下4' , des : '描述一下4' } ,
{ id : 5 , code : '005' , name : '我是name5' , test : '测试一下5' , des : '描述一下5' } ,
{ id : 6 , code : '006' , name : '我是name6' , test : '测试一下6' , des : '描述一下6' } ,
{ id : 7 , code : '007' , name : '我是name7' , test : '测试一下7' , des : '描述一下7' } ,
{ id : 8 , code : '008' , name : '我是name8' , test : '测试一下8' , des : '描述一下8' } ,
{ id : 9 , code : '009' , name : '我是name9' , test : '测试一下9' , des : '描述一下9' } ,
] ;
return (
< >
< DragTable
rowKey= "id"
paddingVertical= { 8 }
paddingHorizontal= { 10 }
columns= { columns}
dataSource= { dataSource}
scroll= { { x : 'max-content' , y : 250 } }
/ >
< / >
) ;
} ;
export default TablePage;
滚动条样式
: : - webkit- scrollbar {
width : 6px;
height : 6px;
background- color: #f5f5f5;
}
: : - webkit- scrollbar- thumb {
background- color: #999 ;
border- radius: 4px;
cursor : pointer;
}
: : - webkit- scrollbar- track {
background- color: #f5f5f5;
}
效果