乐趣区

关于draggable:拖拽组件-dndkit

dnd-kit 我称之为拖拽组件中的王者

git 链接
文章地址

用过 react-dnd 和 react-beautiful-dnd 都没有 dnd-kit 组件灵便以及裸露的数据多(也可能是我钻研的不够深)

应用场景及可实现性能

实现画布类拖拽

  1. 元素是否被拖拽
  2. 元素区域是否被拖入(data 数据利用)
  3. 元素区域是否被拖出(data 数据利用)
  4. 元素区域可接管哪些类型的元素拖入(data 数据利用)
  5. 定位元素拖拽(碰撞算法内可做解决)

拖拽类组件大差不差,有 dragContext、drop、drag 组件,通俗了解 context 实现数据共享,drop 为可被拖拽的区域,drag 为可被拖拽的元素
应用形式看文章,不做解说


<DndContext
         // dndkit 自带碰撞算法,不传则默认为 rectIntersection
        // collisionDetection={rectIntersection}
        // collisionDetection={pointerWithin}
        /**
         * 碰撞算法优化
         *     自定义碰撞算法
         */
        collisionDetection={customCollisionDetectionStrategy}‘/**
         * 传感器配置
         */
        sensors={sensors}
        onDragStart={res => {console.log({ onDragStartMove: res});
          // 本人打印看吧
        }}
        onDragEnd={(res: DragEndEvent) => {console.log({ onDragEnd: res});
         // 拖拽完结(会返回拖拽的以后元素信息及抛弃(搁置)到指定地位的元素信息,可能为 null)}}>
        {children}
        <DragOverlay>
        // 自定义的标识 draggingId - 以后正在被拖拽的元素 id
          {draggingId ? (
            <div
              style={{//  被拖拽元素款式}}></div>
          ) : null}
        </DragOverlay>
<DndContext>

碰撞算法

collisionDetection 自定义碰撞算法,dndkit 会提供一些数据,用户能够在数据根底上进行解决

const customCollisionDetectionStrategy = (rects) => {
    /**
     * active 以后拖拽元素及其 data
     * collisionRect 碰撞元素 data
     * pointerCoordinates 以后指针坐标
     * droppableContainers 所有 dropabble 对象 ->arr
          data: {current: {…}}
          id: ""key:"Droppable-0", // dndkit 给对象减少的字段,可用于排序,数值越大代表以后元素嵌套最深(最上层)node: {current: '以后元素'}
          rect: {current: bottom: 0, height: 96, left: 0, right: 0, top: 0, width: 1920}
     */
    const {active, collisionRect, pointerCoordinates, droppableContainers} = rects;

    // ... 数据处理,需返回碰撞到的元素数组(进行排序)第一个为以后碰撞到的元素
    return arr; 
}

传感器

  const sensors = useSensors(useSensor(MouseSensor));
// MouseSensor dndkit 提供的传感器,默认是应用所有传感器,我这里只应用了 mouse 传感器,碰撞检测返回的数据可能和以后传感器有关联?我这里没做尝试,但碰撞算法的确是依靠于鼠标地位做的解决

应用 drag 或 drop 时可带额定参数

在应用别的拖拽组件时,很多数据处理会很麻烦,dndkit 提供了 data 形式,能够在所有办法里或碰撞算法里返回这些 data,不便数据处理

  // drag 初始化  drop 也一样,官网文档里有
  const {attributes, listeners, setNodeRef} = useDraggable({
    id: dragId,
    disabled: isDragDisabled, // 是否容许拖拽
    data: { // 自定义参数,须要的数据放这里
      ...otherProps,
    },
  });

  // 赋值拖拽过程中的位移款式, 应用 dragOverlay 则不赋值 style
  // const style = {//   transform: CSS.Translate.toString(transform),
  // };

  <div
        ref={setNodeRef}
        // dragOverly 应用时,不给以后元素赋值
        // style={style}
        {...listeners}
        {...attributes}></div>

dragOverly

应用 dragOverly 相当于不更改原对象,当拖拽时会复制一个新的 div(记得将被拖拽的元素的款式赋值给 dragOverly)

拖拽还能够与 resize 兼容应用,本人入手尝试一下吧~


以上都为本人应用过程中用到的办法,还有很多场景或形式没有尝试,但 dndkit 能够实用于更多的场景和形式,真的值得尝试,yyds
以上如果有谬误的中央,欢送斧正~~

退出移动版