BI布局拖拽 (1) 深入react-gird-layout源碼

因為有個拖拉拽的需求,類似于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語言訓練營培訓

當前,醫學與人工智能的深度融合正迎來歷史性發展機遇。華中科技大學同濟醫學院附屬同濟醫院(以下簡稱“同濟醫院”)作為醫療人工智能應用的先行探索者,已在電子病歷輔助書寫、科研數據分析、醫療合同自動化審核等關鍵場景完成試點…