因为有个拖拉拽的需求,类似于quickBi那样的效果。在网上调研了一下发现react-grid-layout实现效果类似,但其也有局限性,比如不支持嵌套,不支持在多个gridLyaout之间互相拖拽。

要求:基于react-grid-layout的思路,改造,让其支持嵌套等效果。
所以本篇只深入拖拽原理,其他的像resize等先略过

react-grid-layout整体思路

首先拉下代码
在这里插入图片描述
主要看ReactGridLayout和GritItem这两个组件。
用法:
在这里插入图片描述

具体更细节用法可以看官网,这里我们知道了他主要接收了layout的一个数组,
结构大概是这样
在这里插入图片描述

w,h,x,y,顾名思义是宽高,在grid布局中第x行,第y列。

大概流程图

ReactGridLayout->GirdItem->ReactDraggable
在这里插入图片描述
react-grid-layout底层依赖了react-draggable这个库。

react-draggable

在这里插入图片描述

看一下react-draggable这个库,拉下来代码主要看
在这里插入图片描述

DraggableCode这个组件,上面的Draggable是有状态管理的。

DraggableCode
在这里插入图片描述
主要是将children clone后,绑上onMouseDown事件等等

在这里插入图片描述
在这里插入图片描述
handleDragStart主要是计算得到获取鼠标按下的坐标,然后保存起来,调用props.onStart传出去。
接着在document上监听mouseMove和mouseup事件。这样一旦开始拖拽,就会触发对应事件。

在看下mousemove触发的hadnleDrag事件
在这里插入图片描述
在这里插入图片描述
createCoreData用来计算当前位移的距离,deltaX表示在x上位移了多少px等。

handleDrag事件也是一样,计算新的位置信息然后调用props.onDrag事件。

在看mouseup触发的handelStop
在这里插入图片描述
也是一样计算位置信息,然后调用props.onStop事件,
最后是一些变量重置事件取消监听等等。

到这里我们知道react-draggable主要是通过绑定mouse事件,然后计算位置信息传出。

ReactGridLayout

现在我们知道了,拖拽能力由底层react-draggable提供。
接着我们看ReactridLayout这一层
用法:
在这里插入图片描述
主要是layout数组,用于保存每个节点的位置信息,以及children,必须是一个数组,且最好是原生标签,而不是react组件。这个后面就会知道了
在这里插入图片描述
这里主要看这三个,
第一个就是渲染children,通过React.Children.map,将children包装了一层。
第二个主要是渲染从外部拖进来的元素,这个后面在看。
第三个则是一个占位符的渲染,像拖拽时下面的红色占位符。

再具体看下processGriditem
在这里插入图片描述
主要是包了一层GridItem组件,然后传入一些属性和对应事件。

我们看下GridItem组件主要做了什么。

GridItem

在这里插入图片描述
可以看到,GridItem主要是将children clone了一下,加上了专属的样式,类名,已经绑定了一个ref,所以我们传入的children最好是原生标签,如果是react组件,需要自己透传这些属性/类名,否则拖拽不生效。
我们这里主要看mixinDraggable函数,拖拽事件,缩放也是通过react-draggable组件能力提供的。
mixin混入,为children提供绑定拖拽的能力。
在这里插入图片描述
这里就比较简单了,直接将child包了一层DraggbaleCore组件。

再看一下这个流程图

在这里插入图片描述

现在理解react-draggable提供底层拖拽能力,主要是绑定时间,获取对应的位置信息,传递给GridtIem组件,然后看下GridItem组件是怎么消费这些信息的。

首先看下onDragStart
在这里插入图片描述
GridItem的onDragStart主要也是计算位置信息,因为最后要计算出x,y的数据,需要以当前容器的x,y为准,所以这里要计算父元素的pLeft和pTop,当前鼠标的left和top减去父元素的left和top就是当前鼠标位于当前容器具体的lefttop

最后将top和left传出去。

再看下onDrag
在这里插入图片描述
这个相对重要,这里开始用到了react-draggable提供的位置信息。比如deltaX,deltaY,通过onDragStart计算的topleft,加上这里位置的deltaX和deltaY,可以得到当前鼠标新的left和top
然后就开始调用calcXY,计算得到当前拖拽元素新的x和y

在这里插入图片描述
主要是根据rowHeight(每一行的高度),加上colsWidth(每一列的宽度),得到新的left和top对应的xy数据。
最后还有一些边界处理,防止出界。然后调用props.onDrag去将新的xy传出去。

最后看下onDragStop事件
在这里插入图片描述
可以看到跟onDrag差不多,主要多了一个变量重置。

最后还可以看下GridItem的一些其他细节,比如css的设定
在这里插入图片描述
先通过calcGridItemPosition,传入当前元素的x,y,w,h得到对应的top和left。
在这里插入图片描述
主要看这两个,如果属于拖拽的时候,那么top和left就是当前鼠标具体的位置信息。
如果不属于拖拽时,就是通过x,y,w,h计算得到的top和left

在这里插入图片描述
在这里插入图片描述
默认使用translate,性能会好一点,但需要注意,如果子级元素有使用position: fixed的,会被当前girdItem影响。

到这里我们就知道了GridItem的主要作用

  • 1 给children加上对应属性,包装ReactDragabble组件,提供拖拽能力。
  • 2 onDragStart计算left和top,onDrag通过消费react-draggble提供的deltaX和deltaY,再根据onDragStart计算的left和top,最后计算得到新的xy,传递出去,onDragStop事件主要是变量重置。
  • 3 计算具体的位置信息,left和top,通过style赋值到对应的dom上。

再来看这个流程图,现在我们理解了
react-draggable提供底层能力
Grid-Item计算位置信息,得到新的xy

在这里插入图片描述
再来看看React-Grid-Layout是怎么消费GridItem提供的数据的。

React-Grid-Layout消费GridItem的数据

在这里插入图片描述

在这里插入图片描述

我们只看drag相关的事件,首先是
onDragStart
在这里插入图片描述
可以看到onDragStart比较简洁,主要是创建了占位符的数据,因为拖拽的时候需要占位符表示新的元素会到哪里去。这样的话占位符就会显示了。
placeholder函数主要就是来显示占位符的,通过activeDrag数据,占位符就会显示。
在这里插入图片描述
然后看下onDrag事件
onDrag

在这里插入图片描述
可以看到,这里主要是调用moveElement函数,传入新的x和y,然后moveElement会模拟当前的元素到新的xy后,发生的碰撞等,然后递归调用,直到当前拖拽元素挪到新的xy后,且不会发生碰撞,至此得到新的layout数组,该数组就是所有元素新的位置信息,最后通过compact处理一下。
compact主要是处理不留空白,有多余位置往上面挤。

moveElement函数比较复杂,这里只需要关注他的功能。

onDrag函数就会得到新的layout,然后重新渲染。最后看下onDragStop

onDragStop
在这里插入图片描述
onDragStop跟onDrag差不多,主要是多了重置变量,清除占位符。然后调用onLayoutMaybeChanged将layout传出去。
至此
在这里插入图片描述
该流程已经基本走通一遍,我们会发现,目前的react-grid-layout是不支持同层级拖拽的,比如从box1拖拽到box2,因为其底层没有处理

下一篇会讲基于当前react-grid-layout和一些灵感后改造的,适合嵌套拖拽/同层级拖拽的布局组件。

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

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

相关文章

CentOS环境搭建-快速升级G++版本

在CentOS环境中快速升级G编译器版本,对于追求最新语言特性的开发者来说至关重要。由于CentOS默认的软件仓库可能不提供G的最新版本,我们通常需要借助第三方软件源,如Developer Toolset或使用Spack等包管理器来完成这一任务。下面将详细介绍两…

分布式接口幂等性的演进和最佳实践,含springBoot 实现(Java版本)

一、背景:为什么需要幂等性 在微服务、分布式架构下,网络不可靠、请求重试机制(如前端超时重发、客户端重发、网关重试、消息消费失败重试等)会带来重复请求,如果接口没有幂等性,可能导致: 重复…

OGRE 3D----6. 背景图片渲染实现详解

1. 背景图片渲染原理 1.1 渲染队列机制 Ogre3D 使用渲染队列(Render Queue)来控制对象的渲染顺序。背景图片需要在所有其他对象之前渲染,因此我们将其设置为 RENDER_QUEUE_BACKGROUND。 1.2 视图变换控制 为了让背景图片始终保持在场景的最远处,我们需要: 使用单位投影…

K线连续涨跌统计与分析工具

K线连续涨跌统计与分析工具 1. 概述 本工具是一个用于分析金融时间序列数据(特别是K线数据)的Python脚本,主要功能是统计连续n根同方向K线后,第n+1根K线的涨跌情况。该工具不仅提供统计分析功能,还支持图形化标记以验证结果,帮助交易者和量化分析师识别市场中的特定模式…

jQuery EasyUI 简介

jQuery EasyUI 简介 引言 随着互联网技术的飞速发展,前端开发变得越来越重要。jQuery EasyUI 作为一款流行的前端UI框架,极大地简化了前端开发的工作流程,提高了开发效率。本文将详细介绍 jQuery EasyUI 的起源、特点、使用方法以及在实际项目中的应用。 一、jQuery Easy…

《测试开发:从技术角度提升测试效率与质量》

测试开发的核心工作内容与职责解析 一、测试开发的定位与核心价值 测试开发(Test Development,简称 TestDev 或 SDET)是融合软件开发能力与测试工程思维的复合型岗位,不同于传统测试工程师,其核心目标是通过技术手段提…

20250710解决KickPi的K7开发板刷机之后出现DDR异常:ch:1 dq0 fail,write:0x1,read:0x20300

20250710解决KickPi的K7开发板刷机之后出现DDR异常:ch:1 dq0 fail,write:0x1,read:0x20300 2025/7/10 20:36[BEGIN] 2025/7/10 19:29:03 /DDR 2f85f4b2d4 cym 25/03/04-14:38.55,fwver: v1.09 In ch0 ttot10 ch0 ttot10 ch1 ttot10 ch0 ttot18 LPDDR4, 2112MHz chan…

Ansible:强大的自动部署工具

文章目录零、Ansible介绍一、安装 ansible二、配置SSH密钥1.检查密钥是否存在2.两边的机器要互相有对方的密钥三、自动部署1.传输文件(1)inventory.ini(2)sync_blt.yml(3)执行命令2.安装软件(1)inventory.ini(2)install_efvs.yml(3)执行命令零、Ansible介绍 Ansible 是一个开源…

Nacos的基本功能以及使用Feign进行微服务间的通信

Nacos是Dynamic Naming and Configuration Service的缩写。What’s Nacos? 下面结合SpringBoot项目,为你介绍Nacos的基本功能以及如何使用Feign进行微服务间的通信。 一、Nacos的基本功能 Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管…

C1编译器和C2编译器Test01

在HotSpot VM中内嵌有两个JIT编译器,分别为Client Compiler和Server Compiler,通常简称为C1编译器和C2编译器。开发人员可以通过如下命令显式指定JVM在运行时到底使用哪一种即时编译器。(1)-client:指定JVM运行在Client模式下,并使…

MongoDB与Spring Boot完整使用指南

目录 1. MongoDB基础概念 什么是MongoDB? 核心概念对比 文档结构示例 2. MongoDB的特点与优势 主要特点 适用场景 3. MongoDB基本操作 基本CRUD操作 插入文档 查询文档 更新文档 删除文档 4. Spring Boot集成MongoDB 步骤1:添加依赖 步骤2:配置数据库连接 …

swift开发,关于应用、页面、视图的生命周期

目录一、应用生命周期(App Lifecycle)UIKit (AppDelegate)SwiftUI (使用 ScenePhase)二、页面生命周期(ViewController Lifecycle)三、视图生命周期(UIView Lifecycle)四、SwiftUI 视图生命周期五、关键对比…

借助HarmonyOS SDK,《NBA巅峰对决》实现“分钟级启动”到“秒级进场”

《NBA巅峰对决》是由望尘科技推出的国内首个真实还原5V5王朝模式的操作篮球手游,提供流畅操作手感和真实篮球赛场体验。丰富的玩法在为玩家带来高质游戏体验的同时,间接带来了启动流程冗长的问题,资源更新阶段的等待感尤为突出。 “我们发现&…

HT-LINK ICE:海速芯32Gbps信号调理芯片,40dB补偿+国产自主,打破高速互联瓶颈!

HT-LINK ICE(TENX海速芯)产品解析与推广文案一、产品定位HT-LINK ICE是TENX海速芯推出的高速信号调理芯片,专为PCIe 5.0/6.0、USB4、Thunderbolt等超高速接口设计,提供信号完整性增强和时钟恢复功能,适用于数据中心、A…

深入剖析 ADL:C++ 中的依赖查找机制及其编译错误案例分析

一、ADL 的定义与背景(一)ADL 的定义ADL(Argument-Dependent Lookup,依赖查找)是 C 中一种特殊的名称查找机制,用于在调用函数时,根据函数参数的类型来确定查找的命名空间范围。ADL 的核心思想是…

【科研绘图系列】R语言绘制相关系数图

文章目录 介绍加载R包数据下载导入数据数据预处理画图系统信息参考介绍 【科研绘图系列】R语言绘制相关系数图 加载R包 library(vegan) library(dplyr)# install.packages("./RVisulizationData/003.mantel test/ggcor_0.9.8.1.tar.gz", repos = NULL, type = &quo…

pharokka phold--快速噬菌体注释工具

pharokka是一款专用于噬菌体基因组及宏基因组的快速标准化注释工具。PS.仍在积极更新中,最近一次更新是在今年6.20。 若需对细菌基因组进行快速标准化注释,建议使用Bakta。启发pharokka开发及命名的Prokka也是优秀选择,但Bakta实为Prokka的卓…

深入浅出 Python Asynchronous I/O:从 asyncio 入门到实战

在现代软件开发中,性能是一个永恒的话题。特别是在处理网络请求、文件读写等 I/O 密集型任务时,传统的同步编程模型可能会因为等待而浪费大量时间。为了解决这个问题,异步编程应运而生。Python 通过内置的 asyncio 库,为开发者提供…

OpenCV颜色矩哈希算法------cv::img_hash::ColorMomentHash

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该类实现了颜色矩哈希算法(Color Moment Hash),用于图像相似性比较。它基于图像在HSV颜色空间中的颜色矩统计特…

上海交大医学院张维拓老师赴同济医院做R语言训练营培训

当前,医学与人工智能的深度融合正迎来历史性发展机遇。华中科技大学同济医学院附属同济医院(以下简称“同济医院”)作为医疗人工智能应用的先行探索者,已在电子病历辅助书写、科研数据分析、医疗合同自动化审核等关键场景完成试点…