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、拖拽要设置最小宽度和最大宽度,防止拖拽过程中找不到元素

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/254968.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

github和gitee

github GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 github可以给提交的代码打上标签&#xff0c;方便版本的迭代和回退&#xff0c;也是一个存储代码的仓库 github工作区 gitee是gitHub的…

Oracle数据表ID自增操作

一、Oracle ID自增长功能介绍 Oracle数据库默认不支持像 SQLServer、MySQL中的自增长&#xff08;auto increment&#xff09;功能&#xff0c;即自动为每一行记录的自增长字段生成下一个值。 二、Oracle ID自增长方法 第一种&#xff0c;通过序列&#xff08;sequence&#…

第四篇:SQL语法-DDL-数据定义语言

大年初一限定篇&#x1f600; &#xff08;祝广大IT学习者、工作者0 error 0 warning&#xff01;&#xff09; 一&#xff0c;DDL数据库操作 &#xff08;一&#xff09;库的查询操作 1.列出所有已定义数据库 show databases; 2.查询当前所处数据库 select database(); &…

【Spring】Bean 的生命周期

一、Bean 的生命周期 Spring 其实就是一个管理 Bean 对象的工厂&#xff0c;它负责对象的创建&#xff0c;对象的销毁等 所谓的生命周期就是&#xff1a;对象从创建开始到最终销毁的整个过程 什么时候创建 Bean 对象&#xff1f;创建 Bean 对象的前后会调用什么方法&#xf…

使用python-numpy实现一个简单神经网络

目录 前言 导入numpy并初始化数据和激活函数 初始化学习率和模型参数 迭代更新模型参数&#xff08;权重&#xff09; 小彩蛋 前言 这篇文章&#xff0c;小编带大家使用python-numpy实现一个简单的三层神经网络&#xff0c;不使用pytorch等深度学习框架&#xff0c;来理解…

c#cad 创建-圆(二)

运行环境 vs2022 c# cad2016 调试成功 一、代码说明 这段代码是一个AutoCAD插件&#xff0c;用于在模型空间中创建一个圆形。 首先&#xff0c;我们需要定义一个命令类CreateCircleCommand&#xff0c;并在命名空间CreateCircleInCad中声明。 在CreateCircleCommand类中&a…

DNS 域名系统——应用层

目录 1 域名系统 DNS 1.1 域名系统 1.2 互联网的域名结构 1.2.1 顶级域名 TLD(Top Level Domain) (1) 国家顶级域名 nTLD (2) 通用顶级域名 gTLD (3) 基础结构域名 (infrastructure domain) 1.3 域名服务器 1.3.1 域名服务器的四种类型 &#xff08;1…

电子电器架构 —— 区域控制器是未来架构的正解吗?

电子电器架构 —— 区域控制器是未来架构的正解吗? 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶…

【数据结构】双向链表(链表实现+测试+原码)

前言 在双向链表之前&#xff0c;如果需要查看单链表来复习一下&#xff0c;链接在这里&#xff1a; http://t.csdnimg.cn/Ib5qS 1.双向链表 1.1 链表的分类 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 1.1.1 单向或者双向 1.1.2 …

【技巧】PCB布局技巧:带条纹的电容

这些都是无极性电容&#xff0c;所以这个条纹不是极性标记。一位读者得回答正确&#xff0c;它代表电容卷绕时&#xff0c;卷绕在外层的那一极。我发现现在很少有工程师知道电容一端的条纹代表什么&#xff0c;也不知道条纹端和不带条纹端互换带来的不同效果。即使你从来不使用…

排序算法的时间复杂度存在下界问题

对于几种常用的排序算法&#xff0c;无论是归并排序、快速排序、以及更加常见的冒泡排序等&#xff0c;这些排序算法的时间复杂度都是大于等于O(n*lg(n))的&#xff0c;而这些排序算法存在一个共同的行为&#xff0c;那就是这些算法在对元素进行排序的时候&#xff0c;都会进行…

16.1 Spring框架_SpringIoC容器与Bean管理(❤❤❤❤)

16.1 Spring框架_SpringIoC容器与Bean管理 1. Spring IOC1.1 IoC控制反转 1. Spring IOC 1.1 IoC控制反转 需要自己查找3种苹果的特色,从而选择符合自己的需求 告诉水果店老板自己的口味,由老板推荐哪种苹果,省去自己查询水果特点 在java中,各种水果就是各种对象,买水果就是创…

uniCloud ---- schema2code

目录 schema2code有两种方式 label属性 component属性 group属性 应用 DB Schema里有大量的信息&#xff0c;其实有了这些信息&#xff0c;前端将无需自己开发表单维护界面&#xff0c;uniCloud可以自动生成新增、修改、列表、详情的前端页面&#xff0c;以及admin端的列…

springboot173疫苗发布和接种预约系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

新版MQL语言程序设计:键盘快捷键交易的设计与实现

文章目录 一、什么是快捷键交易二、使用快捷键交易的好处三、键盘快捷键交易程序设计思路四、键盘快捷键交易程序具体实现1.界面设计2.键盘交易事件机制的代码实现 一、什么是快捷键交易 操盘中按快捷键交易是指在股票或期货交易中&#xff0c;通过使用快捷键来进行交易操作的…

【web前端开发】HTML及CSS简单页面布局练习

案例一 网页课程 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…

在虚拟机上完成Centos安装

Linux学习和使用 前言如何安装Centos初始化操作 使用VMware备份操作系统快照克隆 内容总结参考链接 本人介绍:2023年全国大学生数学建模竞赛国家二等奖,2022年蓝桥杯省二等奖,这里是一个和你一起不断努力,不断前进的程序猿一枚 前言 简单介绍一下本片文章将会讲到的内容:本章节…

【ArcGIS微课1000例】0102:面状要素空洞填充

文章目录 一、实验描述二、实验数据三、实验步骤1. 手动补全空洞2. 批量补全空洞四、注意事项一、实验描述 在对地理数据进行编辑时,时常会遇到面数据中存在个别或大量的空洞,考虑实际情况中空洞的数量多少、分布情况,填充空洞区域可以采用逐个填充的方式,也可以采用快速大…

基于微信小程序的新生报到系统的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【教学类-47-01】UIBOT+IDM下载儿童古诗+修改文件名

背景需求&#xff1a; 去年12月&#xff0c;我去了其他幼儿园参观&#xff0c;这是一个传统文化德育教育特色的学校&#xff0c;在“古典集市”展示活动中&#xff0c;小班中班大班孩子共同现场念诵《元日》《静夜思》包含了演唱版本和儿歌念诵版本。 我马上也要当班主任了&a…