初始 @dnd-kit

基础概念

  • DndContext 用于包装拖拽根组件,DraggableDroppable 都需要包裹在 DndContext
  • Droppable 用于包装接收拖拽元素的组件,使组件能够放置
  • Draggable 用于包装需要拖动的组件,使组件能够被拖拽
  • SortableContext 创建一个拖放排序的容器,其中的子元素可以被拖动并重新排序
  • Sensors 用于检测不同的输入方法,以启动拖动操作、响应移动以及结束或取消操作,内置传感器:指针、鼠标、触摸、键盘

安装依赖

@dnd-kit/core: 6.0.8, @dnd-kit/sortable: 7.0.2, @dnd-kit/utilities: 3.2.1,

  1. useSensors@dnd-kit 库中的一个函数,用于配置和管理拖拽操作的传感器。传感器是用于检测用户交互的输入设备或方式的模块。
  2. useSensor(PointerSensor) 行创建了一个名为 PointerSensor 的传感器实例,并将其添加到 sensors 数组中。PointerSensor 用于捕获指针设备(如鼠标或触摸屏)的交互,允许用户通过拖拽来操作元素。
  3. useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }) 行创建了一个名为 KeyboardSensor 的传感器实例,并将其添加到 sensors 数组中。这里还提供了一个选项对象,指定了 coordinateGetter 函数,用于确定键盘输入的坐标。KeyboardSensor 允许用户使用键盘来操作元素,通常用于键盘控制的排序。
js 复制代码
import React, { FC, useState } from "react";
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
} from "@dnd-kit/core";
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import Item from "./Item";

type ComponentType = {
  fe_id: string;
  title: string;
};

const Container: FC = () => {
  const [items, setItems] = useState<ComponentType[]>([
    { fe_id: "c1", title: "组件1" },
    { fe_id: "c2", title: "组件2" },
    { fe_id: "c3", title: "组件3" },
  ]);

  // 配置和管理拖拽操作的传感器
  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const itemsWithId = items.map((c) => {
    return {
      ...c,
      id: c.fe_id,
    };
  });

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
    >
      <SortableContext
        items={itemsWithId}
        strategy={verticalListSortingStrategy}
      >
        {itemsWithId.map((c) => (
          <Item key={c.id} id={c.id} title={c.title} />
        ))}
      </SortableContext>
    </DndContext>
  );
};

export default Container;

设置 onDragEnd 函数。

  • event 对象中解构出 activeover 属性。active 代表拖动操作的起点元素,over 代表拖动操作的结束点元素。
  • 检查起点元素和结束点元素的 id 是否不相同。
  • 使用 arrayMove 函数将 active 元素从 oldIndex 移动到 newIndex,实现元素的重新排序。
js 复制代码
function handleDragEnd(event: DragEndEvent) {
  const { active, over } = event;
  if (over == null) return;

  if (active.id !== over.id) {
    setItems((items) => {
      const oldIndex = items.findIndex((c) => c.fe_id === active.id);
      const newIndex = items.findIndex((c) => c.fe_id === over.id);
      return arrayMove(items, oldIndex, newIndex);
    });
  }
}

Item.tsx

  1. attributes: 这是一个包含属性的对象,通常应用于拖拽目标元素,以便处理拖拽的交互。这些属性包括样式属性、拖拽相关的属性等,用于实现拖拽时的视觉效果。
  2. listeners: 这是一个包含事件监听器的对象,用于监听拖拽过程中的事件,例如拖拽开始、拖拽结束等。这些事件监听器应该绑定到拖拽目标元素,以便捕获用户的拖拽操作。
  3. setNodeRef: 这是一个回调函数,用于设置拖拽目标元素的引用。通常,你需要将这个回调函数传递给要进行拖拽的元素,以确保能够正确地识别和操作拖拽目标。
  4. transform: 这是一个用于处理拖拽元素的变换效果的 CSS 属性。可以使用它来应用平移(translation)、缩放(scale)等变换,以使拖拽效果看起来更加自然。
  5. transition: 这是一个用于定义拖拽元素的过渡效果的 CSS 属性。可以使用它来创建平滑的过渡动画,使拖拽操作更加流畅。
js 复制代码
import React, { FC } from "react";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

type PropsType = {
  id: string;
  title: string;
};

const Item: FC<PropsType> = (props: PropsType) => {
  const { id, title } = props;

  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    border: "1px solid #ccc",
    margin: "10px 0",
    background: "#f1f1f1",
  };

  return (
    <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
      Item {title}
    </div>
  );
};

export default Item;
相关推荐
老码沉思录3 小时前
React Native 全栈开发实战班 - 数据管理与状态之Zustand应用
javascript·react native·react.js
老码沉思录3 小时前
React Native 全栈开发实战班 :数据管理与状态之React Hooks 基础
javascript·react native·react.js
我认不到你4 小时前
antd proFromSelect 懒加载+模糊查询
前端·javascript·react.js·typescript
凹凸曼打不赢小怪兽6 小时前
react 受控组件和非受控组件
前端·javascript·react.js
鑫宝Code7 小时前
【React】状态管理之Redux
前端·react.js·前端框架
2401_8576100311 小时前
深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
前端·javascript·react.js
fighting ~12 小时前
react17安装html-react-parser运行报错记录
javascript·react.js·html
老码沉思录13 小时前
React Native 全栈开发实战班 - 列表与滚动视图
javascript·react native·react.js
老码沉思录13 小时前
React Native 全栈开发实战班 - 状态管理入门(Context API)
javascript·react native·react.js
老码沉思录16 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js