切换主题
字数
598 字
阅读时间
3 分钟
DndContext 组件是 @dnd-kit/core 的核心组件,它接收一个 onDragEnd 属性:
ts
return (
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<SortableContext items={items} strategy={verticalListSortingStrategy}>
{children}
</SortableContext>
</DndContext>
)
当拖拽结束时,onDragEnd 回调会被触发,它接收一个 DragEndEvent 类型的事件对象:
ts
function handleDragEnd(event: DragEndEvent) {
const { active, over } = event
if (over == null) return
if (active.id !== over.id) {
const oldIndex = items.findIndex(c => c.fe_id === active.id)
const newIndex = items.findIndex(c => c.fe_id === over.id)
onDragEnd(oldIndex, newIndex)
}
}
这个事件对象包含两个重要属性:
active: 被拖拽的元素信息(包含其id)
over: 放置目标的元素信息(包含其id)
在回调函数中,我们通过这两个id找到它们在数组中的索引位置:
const oldIndex = items.findIndex(c => c.fe_id === active.id)
const newIndex = items.findIndex(c => c.fe_id === over.id)
- 最后通过 Redux dispatch 一个 action 来交换这两个位置的元素:
所以整个拖拽排序的流程是:
用户拖拽结束时触发 onDragEnd
获取拖拽元素和目标元素的id
找到这两个元素在数组中的位置
交换这两个位置的元素完成排序
这就是 @dnd-kit 库实现拖拽排序的核心机制。
onDragEnd自动向handleDragEnd传入的event吗 是的。在 DndContext 组件中,当拖拽结束时会自动调用 onDragEnd 属性指定的回调函数,并传入一个 DragEndEvent 类型的事件对象。
这里的 event 参数是由 @dnd-kit/core 库自动传入的,它包含了:
active: 被拖拽的元素信息
over: 放置目标的元素信息
这是 @dnd-kit 库的标准行为,我们不需要手动传入这个事件对象,库会在拖拽结束时自动处理这个过程。
sensors 属性是用来配置拖拽的触发条件的。在这个项目中:
const sensors = useSensors(
ts
const sensors = useSensors(
useSensor(MouseSensor, {
activationConstraint: {
distance: 8, // 8px
},
})
)
这段代码配置了一个鼠标传感器(MouseSensor),设置了以下内容:
useSensors 和 useSensor 是 @dnd-kit/core 提供的 hooks,用于创建和组合传感器
MouseSensor 用于监听鼠标事件
activationConstraint 配置了激活条件:
distance: 8 表示鼠标需要移动至少 8 像素才会触发拖拽,这可以避免用户不小心触发拖拽
这个配置传递给了 DndContext:
贡献者
sunchengzhi