antd Table 表头拖拽宽度

892 阅读1分钟

主要用到组件库react-rnd antd

主要涉及Table 的 components 封装。通过封装components 里面的 header: { cell: ResizableHeader, } 来实现包装rnd 的拖拽事件进行拖拽宽度的计算。 具体代码如下:

表头的封装如下,

    return {
      header: {
        cell: ResizableHeader,
      },
    };
  }, []);

表头封装后,我们需要处理下columns 来进行表头的props 方法传递对应的参数进行宽度的计算

    const temp = list.map(col => {
    // widthCustomList 拖拽后的宽度存储数组,如果这个数组存在就取里面的宽度。
      const width =
        widthCustomList?.find(
          ({ componentId }) => componentId === col.column_id
        )?.width ?? col.width;
      return {
        ...col,
        width,
        // 存在分组 需要遍历处理column
        children: col?.children?.length ? getColumns(col.children) : undefined,
        onHeaderCell: column => {
          return {
            ...column,
            title: typeof col?.title === 'string' ? col?.title : '',
            width,
            // 这里处理列宽度的改变方法。
            onSetColumnWidth: v => {
              if (v !== width) {
                setColumnWidth(v);
              }
            },
          };
        },
      };
    });
    return temp;
  });

对于ResizableHeader 的封装代码如下:

<th
      className={`resizable-container ${className}`}
      style={{
        ...style,
        overflow: 'unset',
      }}
      data-arh-enable="true"
      rowSpan={rowSpan}
      colSpan={colSpan}
    >
      {column_id && (
        <Rnd
          className="resizable-box"
          onResizeStart={() => {
            setResizingStyles(true);
          }}
          onResize={(e, direction, ref, delta, position) => {
            onResize(ref?.style?.width, ref?.style?.height, position);

          }}
          onResizeStop={(e, direction, ref, delta, position) => {
            setResizingStyles(false);
            onResizeStop(ref.style.width, ref.style.height, position);
          }}
          size={{ width: resizableWidth }}
          enableResizing={{
            top: false,
            right: true,
            bottom: false,
            left: false,
            topRight: false,
            bottomRight: false,
            bottomLeft: false,
            topLeft: false,
          }}
          resizeHandleWrapperClass="resizable-handler"
          minWidth={90}
          disableDragging
        >
          <div style={{ width: resizableWidth, height: '100%' }} />
        </Rnd>
      )}
      <div {...rest} style={{ width: resizableWidth }}>
        <span title={title}>{children}</span>
      </div>
    </th>

涉及Rnd 的方法如下处理:

    const nWidth = Number(width.replace('px', ''));
    if (nWidth <= propsWidth) {
      onSetColumnWidth({
        width: Math.max(nWidth, 90),
        componentId: column_id,
      });
    }
    setResizableWidth(nWidth);
  };

  const onResizeStop = width => {
    const nWidth = Number(width.replace('px', ''));
    onSetColumnWidth({
      width: Math.max(nWidth, 90),
      componentId: column_id,
    });
  };

如果想实现列宽的拖拽,只要封装了Table 的components 即可。