大家好,我是王福鵬。
我是一名資深全端工程師,也是 17.5k 開源專案 PMP 的作者。現在我正在開發一個Notion風格的知識庫
HuashuiAI 包括 AI 寫作和協作,使用 React Nextjs 和 Supabase。
在這篇文章中,我將分享如何透過 React 和 dnd-kit 實現樹列表拖放排序。原始碼連結在本文底部。
Dnd-kit 和可排序組件
Dnd-kit 是 React 生態中常見的拖放工具,預設支援排序。
<dndcontext sensors="{sensors}" collisiondetection="{closestCenter}" ondragend="{handleDragEnd}"> <sortablecontext items="{items}" strategy="{verticalListSortingStrategy}"> {items.map(id => <sortableitem key="{id}"> <p>But it can only support the one-level list. If we want to implement a multi-level nested list (or tree), we have to customize it.</p> <h2> Define state date structure </h2> <p>Modern front-end frameworks such as React Vue are data-driven views, so defining data structures first and then considering UI rendering.</p> <p>The most common data structure definition for multi-level nested lists (trees) is as follows, and virtual DOM vnode is also defined in this way.<br> </p> <pre class="brush:php;toolbar:false">const defaultItems = [ { id: 'A', children: [] }, { id: 'B', children: [ { id: 'B1', children: [] }, { id: 'B2', children: [ { id: 'B2a', children: [] }, { id: 'B2b', children: [] }, ], }, ], }, { id: 'C', children: [] }, { id: 'D', children: [ { id: 'D1', children: [] }, { id: 'D2', children: [] }, ], }, { id: 'E', children: [] }, ]
多層巢狀SortableContext不可行
因為狀態資料結構是巢狀的,所以我首先想到的就是巢狀並一起渲染UI結構。
首先,巢狀
然後,繼續巢狀下級
運作效果如下。問題是在同一層級內允許拖放排序,但跨層級排序是不可能的,因為它不是上下文 - 這是合理的
多級轉換為單級是可行的
由於巢狀不可行,因此需要將多層轉換為單級。
但需要為每個item新增祖先Ids屬性,首先是為了顯示層次結構的深度,其次是為了知道它有哪些父節點。
interface IItem { id: string ancestorIds?: string[] children?: IItem[] } function flatten(items: IItem[]): IItem[] { return items.reduce<iitem>((acc, item) => { acc.push(item) if (item.children) { const children = item.children.map((i) => ({ ...i, ancestorIds: [...(item.ancestorIds || []), item.id], // add ancestorIds })) acc.push(...flatten(children)) } return acc }, []) } </iitem>
轉換後的渲染效果如下,現在可以拖曳排序了。不過要修改狀態排序後才會生效。
此外,我們也可以透過祖先ID的層級關係來判斷是否可以移動。父節點不能移動到子節點,否則循環會死。
例如上圖中,如果我們要將B2拖曳到B2a的位置,我們會發現B2a的祖先ID包含B2。這是不可能的,因為您無法將專案拖曳到自己的下屬專案。
修改狀態數據
為了方便操作,資料放置在Zustand全域儲存。
Dnd-kit 將拖曳的元素稱為 activeItem,而將放置的目標位置稱為 overItem。所以修改狀態資料意味著將activeItem移到overItem的位置。
如果是單關,Dnd-kit提供了一個方法arrayMove,可以直接修改。文件連結 https://docs.dndkit.com/presets/sortable
但是在多層嵌套列表(樹)中,需要自己實現,有點麻煩。核心程式碼在這裡,大家可以下載原始碼(文末)參考。
遇到問題
如下圖所示,將A拖曳到B下方時,A會整體移動到B的底部,而不是在B內部。
要解決這個問題,需要判斷B之後是否還有B的子元素,如果有,則將overItem賦值給其子元素
然後將目前活動元素插入items的第一個元素中。
結束
原始碼連結在這裡 https://github.com/wangfupeng1988/react-dnd-sortable-demo
順便說一句,我正在尋找一份國際工作機會,如果你有機會,歡迎透過我的 Github 個人資料聯繫我。
以上是React dnd-kit,實作樹列表拖放排序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript字符串替換方法詳解及常見問題解答 本文將探討兩種在JavaScript中替換字符串字符的方法:在JavaScript代碼內部替換和在網頁HTML內部替換。 在JavaScript代碼內部替換字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 該方法僅替換第一個匹配項。要替換所有匹配項,需使用正則表達式並添加全局標誌g: str = str.replace(/fi

因此,在這裡,您準備好了解所有稱為Ajax的東西。但是,到底是什麼? AJAX一詞是指用於創建動態,交互式Web內容的一系列寬鬆的技術。 Ajax一詞,最初由Jesse J創造

10款趣味橫生的jQuery遊戲插件,讓您的網站更具吸引力,提升用戶粘性!雖然Flash仍然是開發休閒網頁遊戲的最佳軟件,但jQuery也能創造出令人驚喜的效果,雖然無法與純動作Flash遊戲媲美,但在某些情況下,您也能在瀏覽器中獲得意想不到的樂趣。 jQuery井字棋遊戲 遊戲編程的“Hello world”,現在有了jQuery版本。 源碼 jQuery瘋狂填詞遊戲 這是一個填空遊戲,由於不知道單詞的上下文,可能會產生一些古怪的結果。 源碼 jQuery掃雷遊戲

本教程演示瞭如何使用jQuery創建迷人的視差背景效果。 我們將構建一個帶有分層圖像的標題橫幅,從而創造出令人驚嘆的視覺深度。 更新的插件可與JQuery 1.6.4及更高版本一起使用。 下載

本文討論了在瀏覽器中優化JavaScript性能的策略,重點是減少執行時間並最大程度地減少對頁面負載速度的影響。

本文演示瞭如何使用jQuery和ajax自動每5秒自動刷新DIV的內容。 該示例從RSS提要中獲取並顯示了最新的博客文章以及最後的刷新時間戳。 加載圖像是選擇

Matter.js是一個用JavaScript編寫的2D剛體物理引擎。此庫可以幫助您輕鬆地在瀏覽器中模擬2D物理。它提供了許多功能,例如創建剛體並為其分配質量、面積或密度等物理屬性的能力。您還可以模擬不同類型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流瀏覽器。此外,它也適用於移動設備,因為它可以檢測觸摸並具有響應能力。所有這些功能都使其值得您投入時間學習如何使用該引擎,因為這樣您就可以輕鬆創建基於物理的2D遊戲或模擬。在本教程中,我將介紹此庫的基礎知識,包括其安裝和用法,並提供一


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

禪工作室 13.0.1
強大的PHP整合開發環境

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SublimeText3漢化版
中文版,非常好用