react + antd 实现表格的列宽可变,数据量大时页面刷新不卡顿

有需求需要实现表格的列宽拖拉可变,在开始拖拉和放下的过程中在行头显示一条虚线表标明位置,鼠标释放后刷新表格。

上代码!

1. 拖拉传参组件代码

import { FC, useState } from 'react'
import { Resizable } from 'react-resizable'
// 引入react-resizable npm i xxx 或 yarn add xxx
import { deBounce } from '@/utils/utilConvenrt'
// 防抖函数,不是一定需要,目的:更新偏移量不要实时更新
import classnames from 'classnames'

const ResizableTitle: FC<any> = (props) => {
  const { onResize, width, ...restProps } = props;

  // 添加偏移量
  const [offset, setOffset] = useState<number>(0)

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

  return (
    <Resizable
      width={Number(width) + Number(offset)}
      height={0}
      handle={
        <span
          // 有偏移量显示竖线
          className={classnames(['react-resizable-handle', offset && 'active'])}
          // 拖拽层偏移
          style={{ transform: `translateX(${offset}px)` }}
          onClick={e => {
            e.stopPropagation()
            e.preventDefault()
          }}
        />
      }
      // 拖拽事件实时更新
      onResize={(e, { size }) => {
        // 这里只更新偏移量,数据列表其实并没有伸缩
        deBounce(setOffset(size.width - width), 500)
      }}
      // 拖拽结束更新
      onResizeStop={(...argu) => {
        // 拖拽结束以后偏移量归零
        setOffset(0)
        // 这里是props传进来的事件,在外部是列数据中的onHeaderCell方法提供的事件,请自行研究官方提供的案例
        onResize(...argu)
      }}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      {/* <th {...restProps} /> */}
      <th {...restProps} style={{
        overflow: 'visible',
        ...restProps.style,
      }} >
        <div style={{
          width: '100%',
          overflow: 'hidden',
          whiteSpace: 'nowrap',
          textOverflow: 'ellipsis',
       // 此处样式是在th中增加div块,为了解决拖拉时偏移虚线在右侧不出现问题
        }}>{restProps.children}</div>
      </th>
    </Resizable>
  )
}

export default ResizableTitle

2. less代码

.resizableStyle {
  :global {
    .react-resizable {
      position       : relative;
      background-clip: padding-box;
    }

    .react-resizable-handle {
      position: absolute;
      right   : -5px;
      bottom  : 0;
      z-index : 1;
      width   : 10px;
      height  : 100%;
      cursor  : col-resize;
    }

    /** 这里是偏移的时候显示的竖线,只有表头有竖线;
    如果需要联通表格,可查看下篇,目前也有这个需求 */
    .react-resizable-handle.active::before {
      content: '';
      position: absolute;
      left: 50%;
      top: 0;
      bottom: 0;
      border-left: dotted 3px #40a9ff;
    }
  }
}

3.表格引用代码: 主要代码

  components={{ header: { cell: ResizableTitle } }}

  const cols = columns.map((col: any, index: number) => {
    // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
    width += col.width;
    return {
      ...col,
      ellipsis: true,
      onHeaderCell: (column: any) => ({
        width: column.width,
        onResize: handleResize(index)
      })
    }
  });
  const handleResize = (index: number) => (e: any, { size }: { size: any }) => {
    const nextColumns = [...columns];
    nextColumns[index] = {
      ...nextColumns[index],
      width: size.width,
    };
    setColumns(nextColumns);
  };


版权声明:本文为weixin_48192626原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。