應用場景
列表中的成員可鼠標拖拽改變順序
實施步驟
前置引入
import type { DragEndEvent } from '@dnd-kit/core'
import { DndContext } from '@dnd-kit/core'
import {arrayMove,/*垂直列表使用verticalListSortingStrategy,橫向列表使用horizontalListSortingStrategy*/verticalListSortingStrategy,SortableContext,useSortable,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import React from "react"
//這個也是根據列表朝向選擇vertical或horizontal
import { restrictToVerticalAxis } from "@dnd-kit/modifiers"
定義列表成員,這里用的ts
//組件外定義
declare interface DraggableTabPaneProps extends React.HTMLAttributes<HTMLLIElement> {'data-item-key': string
}
const DraggableListNode = ({ children, ...props }: DraggableTabPaneProps) => {const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition } = useSortable({id: props['data-item-key'],})const style: React.CSSProperties = {...props.style,transform: CSS.Translate.toString(transform),transition,}return (<li {...props} ref={setNodeRef} style={style} {...attributes}>{React.Children.map(children, child => {//這里是指定一個拖拽觸發的手柄,如果需要整個列表項觸發拖拽,就不要這個if ((child as React.ReactElement<HTMLElement>).props.className.includes('handlemove')) {return React.cloneElement(child as React.ReactElement, {...listeners,ref: setActivatorNodeRef,})}return child})}</li>)
}
渲染列表
//組件內定義
const data=[{key:1,content:'列表項1'},{key:2,content:'列表項2'}]
const [items,setItems]=useState(data)
//組件輸出部分
<ul><DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={handleDragEnd}><SortableContext items={items.map((i) => i.key)} strategy={verticalListSortingStrategy}>{//上一步聲明的DraggableListNode取代了原生的li標簽items.map(item=>(<DraggableListNode className="listitem" key={item.key} data-item-key={item.key}><span className="handlemove">自定義拖拽手柄</span>{item.content}</DraggableListNode>))}</SortableContext></DndContext>
</ul>
處理拖拽結束事件,改變列表項的順序
//組件內定義
function handleDragEnd({ active, over }: DragEndEvent) {if (active.id !== over?.id) {const activeIndex = items.findIndex((i) => i.key === active.id)const overIndex = items.findIndex((i) => i.key === over?.id)const newlist= arrayMove(items, activeIndex, overIndex)setItems(newlist)}
}
以上。