当前位置:首页 > React

react实现组件拖拽

2026-01-27 08:45:05React

实现拖拽功能的基本方法

使用HTML5的拖放API结合React状态管理实现基础拖拽。需要监听dragstartdragenddragoverdrop事件。

import { useState } from 'react';

function DraggableComponent() {
  const [isDragging, setIsDragging] = useState(false);

  const handleDragStart = (e) => {
    e.dataTransfer.setData('text/plain', 'drag-data');
    setIsDragging(true);
  };

  const handleDragEnd = () => {
    setIsDragging(false);
  };

  return (
    <div
      draggable
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
      style={{
        opacity: isDragging ? 0.5 : 1,
        cursor: 'move'
      }}
    >
      Drag me
    </div>
  );
}

实现拖放目标区域

创建可放置区域需要处理dragoverdrop事件,阻止默认行为是关键。

react实现组件拖拽

function DropZone() {
  const [hasDropped, setHasDropped] = useState(false);

  const handleDragOver = (e) => {
    e.preventDefault();
  };

  const handleDrop = (e) => {
    e.preventDefault();
    const data = e.dataTransfer.getData('text/plain');
    console.log('Dropped data:', data);
    setHasDropped(true);
  };

  return (
    <div
      onDragOver={handleDragOver}
      onDrop={handleDrop}
      style={{
        width: '200px',
        height: '200px',
        border: '2px dashed gray',
        backgroundColor: hasDropped ? 'lightgreen' : 'white'
      }}
    >
      Drop here
    </div>
  );
}

使用第三方库react-dnd

对于复杂拖拽场景,推荐使用react-dnd库。安装命令:npm install react-dnd react-dnd-html5-backend

import { useDrag, useDrop } from 'react-dnd';

function DraggableItem({ id, text, moveItem }) {
  const [{ isDragging }, drag] = useDrag({
    type: 'ITEM',
    item: { id },
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging()
    })
  });

  return (
    <div
      ref={drag}
      style={{
        opacity: isDragging ? 0.5 : 1,
        padding: '8px',
        margin: '4px',
        backgroundColor: 'lightblue',
        cursor: 'move'
      }}
    >
      {text}
    </div>
  );
}

function DropContainer({ children }) {
  const [, drop] = useDrop({
    accept: 'ITEM',
    drop: (item, monitor) => {
      console.log('Dropped item:', item);
    }
  });

  return (
    <div
      ref={drop}
      style={{
        width: '300px',
        minHeight: '200px',
        border: '2px solid gray',
        padding: '16px'
      }}
    >
      {children}
    </div>
  );
}

实现列表排序拖拽

结合react-dnd实现可排序列表需要处理hover状态和位置交换。

react实现组件拖拽

function SortableList({ items, onMove }) {
  return (
    <DropContainer>
      {items.map((item, index) => (
        <SortableItem 
          key={item.id}
          index={index}
          item={item}
          onMove={onMove}
        />
      ))}
    </DropContainer>
  );
}

function SortableItem({ item, index, onMove }) {
  const [, drop] = useDrop({
    accept: 'ITEM',
    hover(draggedItem) {
      if (draggedItem.index !== index) {
        onMove(draggedItem.index, index);
        draggedItem.index = index;
      }
    }
  });

  const [{ isDragging }, drag] = useDrag({
    type: 'ITEM',
    item: { ...item, index },
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging()
    })
  });

  return (
    <div
      ref={(node) => drag(drop(node))}
      style={{
        opacity: isDragging ? 0.5 : 1,
        padding: '8px',
        margin: '4px',
        backgroundColor: 'lightblue',
        cursor: 'move'
      }}
    >
      {item.text}
    </div>
  );
}

性能优化建议

对于大型列表实现拖拽时,考虑使用react-window或react-virtualized进行虚拟滚动。避免在拖拽过程中频繁重渲染整个列表。

自定义拖拽预览可以通过useDragpreview选项实现,或者使用HTML5的setDragImage方法。

const [, drag, preview] = useDrag({
  type: 'ITEM',
  item: { id }
});

useEffect(() => {
  const img = new Image();
  img.src = 'preview.png';
  preview(img);
}, [preview]);

标签: 组件拖拽
分享给朋友:

相关文章

vue实现下拉框组件

vue实现下拉框组件

基础下拉框实现 使用Vue的v-model和v-for指令实现基础下拉框: <template> <select v-model="selectedOption">…

vue实现广告组件

vue实现广告组件

Vue 实现广告组件的核心方法 数据驱动的广告内容渲染 通过 props 接收广告数据(如图片URL、跳转链接等),使用 v-bind 动态绑定属性。典型结构包含 <a> 标签嵌套 <…

vue 实现卡片拖拽

vue 实现卡片拖拽

Vue 实现卡片拖拽 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 drop…

vue 中实现拖拽

vue 中实现拖拽

Vue 中实现拖拽功能 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 drop…

vue实现拖拽

vue实现拖拽

Vue 实现拖拽功能的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。在 Vue 中可以通过绑定这些事件来实现…

前端实现拖拽功能vue

前端实现拖拽功能vue

使用 HTML5 拖放 API 在 Vue 中可以通过 HTML5 的原生拖放 API 实现拖拽功能。需要监听 dragstart、dragover 和 drop 事件。 <template…