likes
comments
collection
share

Antd Table不能列拖动?那我封装一下吧每次用到我用到antd这个库的table组件的时候,若是数据的每一列过长,

作者站长头像
站长
· 阅读数 29

前言

每次用到我用到antd这个库的table组件的时候,若是数据的每一列过长,就难免会遇到不好的影响。于是就有一个需求来啦,需要把表格做成可列拖动的。说干就干,开动。

分析

改造为一个可拖动的表格,最主要的便是改造起表头,然后拖动的每一列的时候,不断改变每一列的宽度,逻辑倒也是不难。

改造

改造表头

首先改造表头我们需要用到一个react-resizable包,实现表头每一列的拖动,我认为这一难点倒是如何写css,一定要注意设置css,否则无法拖动。

import type { ResizeCallbackData } from 'react-resizable'
import { Resizable } from 'react-resizable'
import './index.less'

const Index = (
  props: React.HTMLAttributes<any> & {
    onResize: (e: React.SyntheticEvent<Element>, data: ResizeCallbackData) => void
    width: number
  }
) => {
  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>
  )
}

export default Index

.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; // 光标指示可以水平调整列大小。
}

改造表格

首先用一个用一个状态将每一列的表格存起来,在设置头部单元格的时候再改变每一列表格的宽度,我们在antd table下可以看到一个可以实现这个功能的属性

Antd Table不能列拖动?那我封装一下吧每次用到我用到antd这个库的table组件的时候,若是数据的每一列过长,

 const mergeColumns = columns.map((col, index) => ({
    ...col,
    onHeaderCell: (column: any) => ({
      width: column.width,
      onResize: handleResize(index) as React.ReactEventHandler<any>
    })
  }))

然后我们需要改变在antd table的这个组件改造一下表头部分,在文档中我我们可以看到components这个属性来实现

Antd Table不能列拖动?那我封装一下吧每次用到我用到antd这个库的table组件的时候,若是数据的每一列过长,

Antd Table不能列拖动?那我封装一下吧每次用到我用到antd这个库的table组件的时候,若是数据的每一列过长, 在这个header中引入之前改造的表头

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

具体的代码如下所示

import React, { useState } from 'react'
import { Table } from 'antd'
import ResizableTitle from '@/components/ResizableTitle'
import { ResizeCallbackData } from 'react-resizable'
import { TablePaginationConfig } from 'antd/es/table'

type ResizableTableProps = {
  dataSource: object[]
  columnsList: object[]
  pagination?: TablePaginationConfig | false
  scroll?: object
  rowKey?: string
}

const ResizableTable = (props: ResizableTableProps) => {
  const { dataSource, columnsList, pagination, scroll, rowKey = 'id' } = props

  const [columns, setColumns] = useState(columnsList)
  const handleResize =
    (index: number) =>
      (_: React.SyntheticEvent<Element>, { size }: ResizeCallbackData) => {
        const newColumns = [...columns]
        newColumns[index] = {
          ...newColumns[index],
          width: size.width
        }
        setColumns(newColumns)
      }

  const mergeColumns = columns.map((col, index) => ({
    ...col,
    onHeaderCell: (column: any) => ({
      width: column.width,
      onResize: handleResize(index) as React.ReactEventHandler<any>
    })
  }))
  return (
    <Table
      bordered
      columns={mergeColumns}
      rowKey={rowKey}
      components={{
        header: {
          cell: ResizableTitle
        }
      }}
      scroll={scroll}
      pagination={pagination}
      dataSource={dataSource}
    />
  )
}

export default ResizableTable

这就是基于antd table改造的一个列可拖动的表格,注意,传入的参数,每一列要写好一个宽度,否则不生效。

总结

在改造table的时候我们主要用到了react-resizable这个库来实现改造表格的表头,在改造表格的表头时候注意要设置其中的样式,使其可拖动,最后便是在拖动的时候不断重新写入每一列的宽度啦。

转载自:https://juejin.cn/post/7418085899713544207
评论
请登录