当前位置: 首页 > news >正文

Antd+React+react-resizable实现表格拖拽功能

1、先看效果

2、环境准备

在package.json 引入相关的依赖

  "dependencies": {"antd": "^5.4.0","react-resizable": "^3.0.4",},"devDependencies": {"@types/react": "^18.0.33","@types/react-resizable": "^3.0.1",}

3、功能实现

一、拖拽组件实现

1、导入所需组件:在你的代码文件中导入所需的组件:

import { Resizable, ResizableProps } from 'react-resizable';

 2、创建可调整大小的列组件:为了实现表格拖拽功能,你需要为每一列创建一个可调整大小的组件。在每个表格列的头部,使用Resizable组件来包裹列的内容:

/*** 公共组件:实现拖拽*/
import { isNumber } from 'lodash';
import { StyleHTMLAttributes } from 'react';
import { Resizable, ResizableProps } from 'react-resizable';type ResizableTitleProps = ResizableProps & {resizable?: boolean;style: StyleHTMLAttributes<any>;
};const ResizableTitle = (props: ResizableTitleProps) => {const { onResize, width, resizable, ...restProps } = props;if (!width || !resizable) {return <th {...restProps} />;}let resizeWidth: any = width;if (!isNumber(resizeWidth)) {resizeWidth = Number(resizeWidth.replace('px', ''));}return (<Resizablewidth={resizeWidth}height={0}handle={<spanclassName="react-resizable-handle"onClick={(e) => {e.stopPropagation();}}/>}onResize={onResize}draggableOpts={{ enableUserSelectHack: true }}// maxConstraints={[800, 800]}><th{...restProps}style={{...restProps?.style,width: `${resizeWidth}px`,borderRight: '1px solid rgba(2, 9, 23, 70%)',}}/></Resizable>);
};export default ResizableTitle;

 在上面的代码中,我们使用Resizable组件来包裹了列的内容。handle属性定义了列的调整大小的手柄样式,你可以根据需要自定义。draggableOpts属性用于配置调整大小的选项。

 二、在antd写入tab,并引用该拖拽组件

1、在table的components属性中,引入该拖拽组件

 <Table...{...(isResizable? {components: {header: {cell: ResizableTitle, // 动态拖拽设置列宽},},}: {})}columns={getColumns(currentColumns)}{...props}/>

 2、对每一列的onHeaderCell都加上拖拽的属性resizable,控制该列是否可拖拽,配置onResize的回调方法

  const getColumns = (columns: any) => {return (columns || []).map((col: any, idx: number) => {return {...col,onHeaderCell: (column: any) => ({width: column.width || 100,resizable: isResizable && !column?.fixed,onResize: handleResize(idx, col.dataIndex as string),}),};});};

 3、拖拽后更新表格的列宽

// 拖拽后更新表格宽度const handleResize =(index: number, colDataIndex?: string) =>(e: any, { size }: { size: { width: number } }) => {if (!colDataIndex) {return;}setCurrentColumns((pre) => {let temp = [...pre];temp[index] = {...temp[index],width: size.width < 50 ? 50 : size.width,};computedWidth(temp);return temp;});};

 4、具体实现如下:

import { Table } from 'antd';
import clsx from 'clsx';
import React, { useEffect, useState } from 'react';
import ResizableTitle from './ResizableTitle';
import styles from './index.less';export interface ListTableProps {className?: any;rowClassName?: any;dimension?: number;columns?: any;dataSource?: any;pagination?: any;scroll?: object;virtual?: boolean;rowKey?: any;isShowScrollX?: boolean;vid?: string;isResizable?: boolean; //是否可退拽onChange?: (pagination: any, filters: any, sorter: any) => void;
}// 暂无数据组件
const NoDataComponent = () => {return (<div className={clsx(['h-[250px]', 'flex justify-center items-center'])}><divclassName={clsx(['w-[76px] h-[94px]','bg-[url("/images/no-data.svg")] bg-no-repeat',])}/></div>);
};const ListTable: React.FC<ListTableProps> = ({className,rowClassName = () => '',onChange,dataSource,isShowScrollX,defaultFixedNode,columns: initCols,isResizable,vid = 'resize_table',...props
}) => {const [currentColumns, setCurrentColumns] = useState([]);const [leftRightNodeIsFixed, setLeftRightNodeIsFixe] =useState(defaultFixedNode); // 左右节点是否固定useEffect(() => {setCurrentColumns(initCols);}, [initCols]);useEffect(() => {setCurrentColumns(initCols);}, [initCols]);// 计算宽度,当出现底部滚动条时,最左最右节点固定const computedWidth = (columns: any) => {const widthAll =document.getElementsByClassName('ant-table-body')?.[0]?.clientWidth;const currentTabWidth = (columns || []).reduce((pre: number, cur: any) => {return Number(pre) + (Number(cur?.width) || 0);}, 0);setLeftRightNodeIsFixe(currentTabWidth > widthAll);};
// 拖拽后更新表格宽度const handleResize =(index: number, colDataIndex?: string) =>(e: any, { size }: { size: { width: number } }) => {if (!colDataIndex) {return;}setCurrentColumns((pre) => {let temp = [...pre];temp[index] = {...temp[index],width: size.width < 50 ? 50 : size.width,};computedWidth(temp);return temp;});};const getColumns = (columns: any) => {return (columns || []).map((col: any, idx: number) => {return {...col,onHeaderCell: (column: any) => ({width: column.width || 100,resizable: isResizable && !column?.fixed,onResize: handleResize(idx, col.dataIndex as string),}),};});};return (<TablerowClassName={(record, index) => {return rowClassName(record, index);}}locale={{ emptyText: <NoDataComponent /> }}{...(isResizable? {components: {header: {cell: ResizableTitle, // 动态拖拽设置列宽},},}: {})}columns={getColumns(currentColumns)}onChange={onChange}dataSource={dataSource}{...props}/>);
};export default ListTable;

4、常见问题:

1、拖拽时,鼠标离开,拖拽被还原,80%原因是因为父组件触发了useState更新,column被还原成初始态,

2、拖拽要设置最小宽度和最大宽度,防止拖拽过程中找不到元素

相关文章:

Antd+React+react-resizable实现表格拖拽功能

1、先看效果 2、环境准备 在package.json 引入相关的依赖 "dependencies": {"antd": "^5.4.0","react-resizable": "^3.0.4",},"devDependencies": {"types/react": "^18.0.33","types…...

StringBuilder类常用方法(Java)

StringBuilder类常用方法 StringBuilder 是 Java 中常用的字符串缓冲区类&#xff0c;适用于频繁修改字符串的场景。 1. append(): 将指定字符串、字符、布尔值或其他数据类型的表示追加到字符串缓冲区的末尾。 StringBuilder sb new StringBuilder("Hello"); sb.…...

Iceberg从入门到精通系列之二十一:Spark集成Iceberg

Iceberg从入门到精通系列之二十一&#xff1a;Spark集成Iceberg 一、在 Spark 3 中使用 Iceberg二、添加目录三、创建表四、写五、读六、Catalogs七、目录配置八、使用目录九、替换会话目录十、使用目录特定的 Hadoop 配置值十一、加载自定义目录十二、SQL 扩展十三、运行时配置…...

Linux的进程信号

注意&#xff1a;首先需要提醒一个事情&#xff0c;本节提及的进程信号和下节的信号量没有任何关系&#xff0c;请您区分对待。 1.信号概念 1.1.生活中的信号 我们在生活中通过体验现实&#xff0c;记忆了一些信号和对应的处理动作&#xff0c;这意味着信号有以下相关的特点&…...

svn常用命令及过滤文件 global ignore pattern

SVN常用命令详解和global ignore pattern Subversion&#xff08;SVN&#xff09;是一个版本控制系统&#xff0c;广泛用于软件开发项目中。它能够追踪文件的变更&#xff0c;并且允许多人在同一个项目中协同工作。以下是一些常用的SVN命令及其用法。 1. 检出代码 要从SVN服…...

【QT+QGIS跨平台编译】之二十九:【HDF5+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、HDF5介绍二、文件下载三、文件分析四、pro文件一、HDF5介绍 HDF5(层次数据格式第5版)是一种用于存储和组织大量数据的文件格式和技术集合。它由美国国家超级计算应用中心(NCSA)开发,旨在解决复杂数据的存储和分布问题。HDF5支持各种数据类型,能够有效地存储…...

React 中实现拖拽功能-插件 react-beautiful-dnd

拖拽功能在平时开发中是很常见的&#xff0c;这篇文章主要使用react-beautiful-dnd插件实现此功能。 非常好用&#xff0c;附上GitHub地址&#xff1a;https://github.com/atlassian/react-beautiful-dnd 安装及引入 // 1.引入 # yarn yarn add react-beautiful-dnd# npm npm…...

golang 引入swagger(iris、gin)

golang 引入swagger&#xff08;iris、gin&#xff09; 在开发过程中&#xff0c;我们不免需要调试我们的接口&#xff0c;但是有些接口测试工具无法根据我们的接口变化而动态变化。文档和代码是分离的。总是出现文档和代码不同步的情况。这个时候就可以在我们项目中引入swagge…...

Java开发IntelliJ IDEA2023

IntelliJ IDEA 2023是一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Java开发人员设计。它提供了许多特色功能&#xff0c;帮助开发人员更高效地编写、测试和调试Java应用程序。以下是一些IntelliJ IDEA 2023的特色功能&#xff1a; 智能代码编辑器&…...

LeetCode LCP 30.魔塔游戏:贪心(优先队列)

【LetMeFly】LCP 30.魔塔游戏&#xff1a;贪心&#xff08;优先队列&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/p0NxJO/ 小扣当前位于魔塔游戏第一层&#xff0c;共有 N 个房间&#xff0c;编号为 0 ~ N-1。每个房间的补血道具/怪物对于血量影响记于…...

Oracle的权限

通过用户登录plsql工具后&#xff0c;如果在创建视图(或其他对象)时&#xff0c;没有指明视图或对象的用户&#xff0c;该视图或对象将直接创建在当前登录用户下。 GRANT SELECT ON user2.table1 TO user1;//将用户2的表1的select权限给用户1 GRANT ALL ON user2.table1 TO u…...

20240206三次握手四次挥手

TCP和UDP异同点 相同点&#xff1a;同属于传输层的协议 不同点&#xff1a; TCP ----> 稳定 1> 提供面向连接的&#xff0c;可靠的数据传输服务 2> 传输过程中&#xff0c;数据无误、数据无丢失、数据无失序、数据无重复 1、TCP会给每个数据包编上编号&#xff…...

Navicat的使用教程,操作详解

这篇文章主要针对mysql数据库。 在使用Navicat之前&#xff0c;首先要确保你在本地已经安装好了&#xff0c;mysql数据库&#xff0c;安装教程可以参考我的另一篇博文 在windows平台上mysql的安装教程-CSDN博客 1.Navicat连接你的数据库 连接名&#xff0c;随便写&#xff0c…...

Git―基本操作

Git ⛅认识 Git⛅安装 GitCentos(7.6)Ubuntu ⛅Git―基本操作创建本地仓库&#x1f342;配置本地仓库&#x1f342;工作区, 暂存区, 版本库&#x1f342;版本库工作区 添加文件&#x1f342;查看文件&#x1f342;修改文件&#x1f342;版本回退&#x1f342;☃️案例 撤销修改…...

【PostgreSQL内核学习(二十六) —— (共享数据缓冲区)】

共享数据缓冲区 概述共享数据缓冲区管理共享缓冲区管理的核心功能包括&#xff1a; 共享数据缓冲区的组织结构初始化共享缓冲池BufferDesc 结构体InitBufferPool 函数 如何确定请求的数据页面是否在缓冲区中&#xff1f;BufferTag 结构体RelFileNode 结构体ForkNumber 结构体Re…...

word调整论文格式的记录

页眉的分章显示内容 效果&#xff1a; 步骤&#xff1a; 确保“显示/隐藏的标记”符号打开点亮 前提是章节前面有“分节符&#xff08;下一页&#xff09;”&#xff0c;没有则添加&#xff0c;在菜单栏“布局”——》“下一页” 添加页眉&#xff0c;双击页眉&#xff0c;选…...

android.MediaMuxer时间裁剪

使用MediaMuxer裁剪视频_安卓muxer 裁剪视频画布-CSDN博客 关键步骤 mediaExtractor.seekTo(beginTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);long presentTimeUs mediaExtractor.getSampleTime(); if (presentTimeUs > endTime)break; 功能代码 VideoView videoVie…...

【蓝桥杯选拔赛真题91】Scratch筛选数据 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 scratch筛选数据 一、题目要求 编程实现 二、案例分析 1、角色分析...

英语学习——16组英语常用短语

第1组&#xff1a;look look at 看 look for 寻找 look up 查阅&#xff0c;向上看 look out 向外看&#xff0c;小心 look after 照顾 look like 看起来像 look through 浏览 look into 向里看 look around 环顾四周 look forward to 期盼 look ahead 向前看 Look…...

unity 增加系统时间显示、FPS帧率、ms延迟

代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;using UnityEngine;public class Frame : MonoBehaviour {// 记录帧数private int _frame;// 上一次计算帧率的时间private float _lastTime;// 平…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...