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

1、先看效果

2、环境准备

  "dependencies": {
    "antd": "^5.4.0",
    "react-resizable": "^3.0.4",

  },
  "devDependencies": {
    "@types/react": "^18.0.33",
    "@types/react-resizable": "^3.0.1",
  }

3、功能实现

一、先把拖拽组件写好

 

/**
 * 公共组件:实现拖拽
 */
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 (
    <Resizable
      width={resizeWidth}
      height={0}
      handle={
        <span
          className="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;

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

/**
 * 公共组件:静态表格
 */

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'])}>
      <div
        className={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 (
    <Table
      rowClassName={(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、拖拽要设置最小宽度和最大宽度,防止拖拽过程中找不到元素

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端面试题——Vue的双向绑定

前言 双向绑定机制是Vue中最重要的机制之一&#xff0c;甚至可以说是Vue框架的根基&#xff0c;它将数据与视图模板相分离&#xff0c;使得数据处理和页面渲染更为高效&#xff0c;同时它也是前端面试题中的常客&#xff0c;接下来让我们来了解什么是双向绑定以及其实现原理。…

Python的包安装工具——pip命令大全

对于大多数使用Python的人来说&#xff0c;一定知道pip这个包安装工具&#xff0c;但是对pip可能还不是很了解&#xff0c;今天作者给大家介绍一下pip的命令&#xff0c;以方便灵活使用pip。 一、pip工具使用方法 pip的语法如下&#xff1a; pip [options] 式中&#xff1a…

InverseMatrix3D

InverseMatrixVT3D: An Efficient Projection Matrix-Based Approach for 3D Occupancy Prediction https://github.com/DanielMing123/InverseMatrixVT3D InverseMatrix3D过程总结如下&#xff1a; 1. 用2D backbone提取N个视角的多尺度图像特征&#xff0c;表示如下&#xf…

机器学习聚类算法

聚类算法是一种无监督学习方法&#xff0c;用于将数据集中的样本划分为多个簇&#xff0c;使得同一簇内的样本相似度较高&#xff0c;而不同簇之间的样本相似度较低。在数据分析中&#xff0c;聚类算法可以帮助我们发现数据的内在结构和规律&#xff0c;从而为进一步的数据分析…

Centos 内存和硬盘占用情况以及top作用

目录 只查看内存使用情况&#xff1a; 内存使用排序取前5个&#xff1a; 硬盘占用情况 定位占用空间最大目录 top查看cpu及内存使用信息 前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&…

Python 潮流周刊#38:Django + Next.js 构建全栈项目

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。本周刊开源&#xff0c;欢迎投稿[1]。另有电报频道[2]作为副刊&#xff0c;补充发布更加丰富的资讯&#xff0c;…

protoc结合go完成protocol buffers协议的序列化与反序列化

下载protoc编译器 下载 https://github.com/protocolbuffers/protobuf/releases ps: 根据平台选择需要的编译器&#xff0c;这里选择windows 解压 加入环境变量 安装go专用protoc生成器 https://blog.csdn.net/qq_36940806/article/details/135017748?spm1001.2014.3001.…

canvas图片上设置镂空文字效果

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

VR全景技术可以应用在哪些行业,VR全景技术有哪些优势

引言&#xff1a; VR全景技术&#xff08;Virtual Reality Panorama Technology&#xff09;是一种以虚拟现实技术为基础&#xff0c;通过360度全景影像、立体声音、交互元素等手段&#xff0c;创造出沉浸式的虚拟现实环境。该技术不仅在娱乐领域有着广泛应用&#xff0c;还可…

方案分享:F5怎么样应对混合云网络安全?

伴随着云计算走入落地阶段&#xff0c;企业的云上业务规模增长迅猛。具有部署灵活、成本低、最大化整合现有资产、促进业务创新等优点的混合云逐渐成为企业选择的部署方式。与此同时&#xff0c;安全运营的复杂度进一步提高。比如安全堆栈越来越复杂、多云基础设施和应用添加网…

小白Linux学习笔记-Linux开机启动流程

Linux 开机启动流程 文章目录 Linux 开机启动流程启动流程概览详细讲解开机软件 —— BIOS、Grub名词解释流程解释BIOS 开机文档 —— menu.lst、grub.confGrub 配置文档流程解释 init 程序流程解释init 执行的相关文件 run-level(启动等级) 相关的命令实验rhel6 单用户模式修改…

机器学习数据预处理方法(数据重编码)

文章目录 [TOC]基于Kaggle电信用户流失案例数据&#xff08;可在官网进行下载&#xff09;一、离散字段的数据重编码1.OrdinalEncoder自然数排序2.OneHotEncoder独热编码3.ColumnTransformer转化流水线 二、连续字段的特征变换1.标准化&#xff08;Standardization&#xff09;…

数字人客服技术预研

技术洞察 引言 在当今数字化时代&#xff0c;不断进步和创新的人工智能&#xff08;AI&#xff09;技术已经渗透到各行各业中。随着AI技术、大模型技术逐步发展&#xff0c;使得数字人的广泛应用成为可能&#xff0c;本文将跟大家一起探讨AI数字人客服的概念、优势、应用场景…

苹果电脑录制视频在哪里?教你快速找到它!

录制电脑屏幕已成为了许多用户日常所需的操作&#xff0c;无论是录制在线课程、游戏过程&#xff0c;还是网络会议&#xff0c;一款好的录屏软件能帮助用户高效、便捷地完成任务。苹果电脑是当今主流的计算机设备之一&#xff0c;可是很多用户不知道苹果电脑录制视频在哪里。在…

麒麟信安登录央视, 深度展现为中国信息安全铸“魂”之路

近日&#xff0c;麒麟信安登录央视频道&#xff0c;《麒麟信安——为中国信息安全铸“魂”》在CCTV-4中文国际频道、CCTV-7国防军事频道、CCTV-10 科教频道、CCTV-12社会与法频道、CCTV-17农业农村频道&#xff0c;向亿万观众深度展现麒麟信安为中国信息安全铸“魂”之路。 麒…

Kafka相关内容复习

为什么要用消息队列 解耦 允许你独立的扩展或修改两边的处理过程&#xff0c;只要确保它们遵守同样的接口约束。 可恢复性 系统的一部分组件失效时&#xff0c;不会影响到整个系统。消息队列降低了进程间的耦合度&#xff0c;所以即使一个处理消息的进程挂掉&#xff0c;加入队…

XML:可扩展标记语言

XML&#xff1a;可扩展标记语言 主要内容 XML介绍DTDXSDDOM解析SAX解析 学习目标 知识点要求XML介绍掌握DTD掌握XSD掌握DOM解析掌握SAX解析掌握 一、XML介绍 1. 简介 XML&#xff08;Extensible Markup Language&#xff09;可扩展标记语言。严格区分大小写。 2. XML和…

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁&#x1f44a; 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题背景 今天寸铁在…

云上未来:探索云计算的技术变革与应用趋势

一、云计算的起源和演进 1.1 早期计算模型 在探讨云计算的起源和演进之前&#xff0c;理解早期的计算模型对于构建全面的视角至关重要。早期计算模型的发展奠定了云计算的基础&#xff0c;为其演进提供了技术和理念的支撑。 1.1.1 集中式计算模型 在计算技术的早期阶段&…

苹果 Vision Pro 产地首次公布:原汁原味的中国制造丨 RTE 开发者日报 Vol.143

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…