当前位置: 首页 > 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;// 平…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...