【RaETable】🚀🚀🚀告别Form,RaETable表格列宽度支持拖动调整了,附带原理说明

简介: 【RaETable】🚀🚀🚀告别Form,RaETable表格列宽度支持拖动调整了,附带原理说明

raETablereactantd Easy Table 的缩写。旨在让开发者在react中使用 antdTable时更 easy。

Github: https://github.com/mmdctjj/raetable

npm: https://www.npmjs.com/package/raetable

文档:https://mmdctjj.github.io/raetable


🚀 变更内容

最近工作的需求变动,antd表格的宽度需要支持拖动调整。

调研了一圈,呼声最高的方案是使用react-resizable库实现。

实现之后发现这个功能特别适合 RaETable 于是,我也给这个组件增加了这个功能。不过,不用担心,这个功能默认是关闭的,当你设置resizetrue 时才会开启该功能。

效果可以直接看这个示例

录制的工具限制,只有15帧动画,感兴趣的话可以到官网实际操作下。

https://mmdctjj.github.io/raetable/components/e-table#表格宽度自适应

🚀 实现原理

实现原理:

  • react-resizable提供了Resizable组件用于包括th元素,成为可以拖拽的元素。
  • 采用antd``Table组件提供的components属性,覆盖表头元素
  • 每次拖拽之后将最新的列宽度值设置为列的真实宽度值

https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129

export interface TableComponents<RecordType> {
  table?: CustomizeComponent;
  header?: {
    wrapper?: CustomizeComponent;
    row?: CustomizeComponent;
    cell?: CustomizeComponent;
  };
  body?:
    | CustomizeScrollBody<RecordType>
    | {
        wrapper?: CustomizeComponent;
        row?: CustomizeComponent;
        cell?: CustomizeComponent;
      };
}

🚀 实现过程

💎 重写表头组件

import { Resizable, ResizeCallbackData } from 'react-resizable';
import 'react-resizable/css/styles.css';
const ResizableTitle = (props: {
  [x: string]: any;
  onResize: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | undefined;
  width: number;
}) => {
  const { onResize, width, ...restProps } = props;
  if (!width) {
    return <th {...restProps} />;
  }
  return (
    <Resizable width={width} height={0} onResize={onResize}>
      <th {...restProps} />
    </Resizable>
  );
};

💎 覆盖表头组件

const ResizeTable = (
  props: JSX.IntrinsicAttributes &
    TableProps<any> & { children?: React.ReactNode } & {
      ref?: React.Ref<HTMLDivElement> | undefined;
    },
) => {
  const [columns, setColumns] = useState(props.columns ?? []);
  return (
    <Table
      {...props}
      columns={columns}
      components={{
        header: {
          cell: ResizableTitle,
        },
      }}
      scroll={{ x: 'max-content' }} // 添加滚动条以适应自适应宽度
    />
  );
};

💎 动态的更新表格列宽度

const handleResize =
    (index: number) =>
    (event: any, { size }: any) => {
      setColumns((prevColumns) => {
        const nextColumns = [...prevColumns];
        nextColumns[index] = {
          ...nextColumns[index],
          width: size.width,
        };
        return nextColumns;
      });
    };
  const resizableColumns = columns?.map((col: any, index: number) => ({
    ...col,
    onHeaderCell: (column: { width: number }) => ({
      width: column.width,
      onResize: handleResize(index),
    }),
  }));

完整代码如下

import { Table, TableProps } from 'antd';
import React, { useState } from 'react';
import { Resizable, ResizeCallbackData } from 'react-resizable';
import 'react-resizable/css/styles.css';
const ResizableTitle = (props: {
  [x: string]: any;
  onResize: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | undefined;
  width: number;
}) => {
  const { onResize, width, ...restProps } = props;
  if (!width) {
    return <th {...restProps} />;
  }
  return (
    <Resizable width={width} height={0} onResize={onResize}>
      <th {...restProps} />
    </Resizable>
  );
};
const ResizeTable = (
  props: JSX.IntrinsicAttributes &
    TableProps<any> & { children?: React.ReactNode } & {
      ref?: React.Ref<HTMLDivElement> | undefined;
    },
) => {
  const [columns, setColumns] = useState(props.columns ?? []);
  const handleResize =
    (index: number) =>
    (event: any, { size }: any) => {
      setColumns((prevColumns) => {
        const nextColumns = [...prevColumns];
        nextColumns[index] = {
          ...nextColumns[index],
          width: size.width,
        };
        return nextColumns;
      });
    };
  const resizableColumns = columns?.map((col: any, index: number) => ({
    ...col,
    onHeaderCell: (column: { width: number }) => ({
      width: column.width,
      onResize: handleResize(index),
    }),
  }));
  return (
    <Table
      {...props}
      columns={resizableColumns}
      components={{
        header: {
          cell: ResizableTitle,
        },
      }}
      scroll={{ x: 'max-content' }} // 添加滚动条以适应自适应宽度
    />
  );
};
export default ResizeTable;

🎉 最后

RaETable 是我独立开发的antd基于table组件的一揽子生态集合,常常用于B端业务处理,在敏捷开发场景事半功倍,效果显著,希望可以帮助更多的开发者。

如果你在使用中有任何的问题,都可以联系我。

好了,今天的分享就这些,文章中错误的地方欢迎指正。

相关文章
|
3月前
|
数据采集 数据挖掘 API
跨境卖家必看:1688店铺订单列表,订单详情,订单物流接口详解
1688平台提供丰富的API接口,涵盖商品、订单、物流等核心业务场景。主要接口包括:**order.list**(查询订单列表)、**order.get**(获取订单详情)及**logistics.track**(查询物流信息),均支持GET请求方式,广泛应用于跨境寻源、数据采集、ERP系统等场景。
|
数据采集 缓存 前端开发
获取任意网站 icon 这件事并没那么简单
本文源自开发者Pony在创作“标签星球”过程中遇到的一个需求:如何高效获取并展示网站的Logo。为此,他深入研究并自建了一套图标获取与托管服务。标签星球是一款基于浏览器收藏夹的启动页应用,能将收藏夹转换为导航页形式,并支持模糊搜索及收藏夹分享等功能。在寻找合适服务时,Pony发现现有解决方案要么受限于技术壁垒,要么覆盖范围有限,这促使他着手搭建自己的服务。文章详细介绍了该服务的设计思路和技术实现过程,包括对多种网站图标设置方法的分析、链接处理策略、获取流程、缓存机制以及错误处理方案等。
315 2
|
前端开发 JavaScript
React配合axios请求拦截校验session,403跳转至登陆页面
React中使用axios进行请求拦截,通过自定义事件监听和响应拦截实现403状态码时的自动登录页面跳转。
419 2
|
10月前
|
JSON 测试技术 数据格式
Playwright 测试报告器
Playwright 测试报告器
383 4
|
Java
flyway报错SLF4J: No SLF4J providers were found.或者SLF4J: Defaulting to no-operation (NOP) logger implem
flyway报错SLF4J: No SLF4J providers were found.或者SLF4J: Defaulting to no-operation (NOP) logger implem
606 1
|
11月前
|
监控 安全 网络安全
SDWAN高效便捷的异地组网技术
【10月更文挑战第12天】SDWAN高效便捷的异地组网技术
267 0
|
小程序 Android开发 iOS开发
微信小程序-虚拟支付:适用场景 / iPhone调试用支付成功,Android调用失败,提示“小程序支付能力已被限制” / “errMsg“.“requestPayment:fail banned”
微信小程序-虚拟支付:适用场景 / iPhone调试用支付成功,Android调用失败,提示“小程序支付能力已被限制” / “errMsg“.“requestPayment:fail banned”
944 0
|
资源调度 前端开发
antd table表头拖拽实现(一)
antd table表头拖拽实现
1573 0
|
Ubuntu 架构师 Linux
内存泄露专题(5)动态内存追踪大杀器:bcc
内存泄露专题(5)动态内存追踪大杀器:bcc
394 0
|
SQL 存储 监控
轻松玩转全链路监控
好的产品总是能给予用户最轻松的使用体验,并在实际生产中发挥出巨大的业务价值。我们不妨从现在开始,就将所有微服务应用通过无侵入的方式接入ARMS,构建一体化的全链路监控体系,而不是等到真正遇到生产故障的那一天,为了定位问题而费尽周折。
10552 93
轻松玩转全链路监控