当前位置:首页 > React

react如何实现拖拽布局

2026-03-11 04:47:57React

实现拖拽布局的核心方法

React 中实现拖拽布局通常需要借助第三方库,以下是几种主流方案及其实现方式:

使用 react-dnd

react-dnd 是 React 生态中功能强大的拖拽库,适合复杂场景。

安装依赖:

npm install react-dnd react-dnd-html5-backend

基础代码结构:

import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

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

  return (
    <div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {text}
    </div>
  );
};

const DropZone = ({ children }) => {
  const [{ canDrop }, drop] = useDrop(() => ({
    accept: 'ITEM',
    drop: () => ({ name: 'DropZone' }),
    collect: (monitor) => ({
      canDrop: !!monitor.canDrop(),
    }),
  }));

  return (
    <div ref={drop} style={{ background: canDrop ? 'lightgreen' : 'white' }}>
      {children}
    </div>
  );
};

const App = () => (
  <DndProvider backend={HTML5Backend}>
    <DropZone>
      <DraggableItem id="1" text="Drag me" />
    </DropZone>
  </DndProvider>
);

使用 react-beautiful-dnd

专为列表拖拽优化的库,适合排序场景。

安装依赖:

npm install react-beautiful-dnd

示例代码:

import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

const items = [
  { id: '1', content: 'Item 1' },
  { id: '2', content: 'Item 2' },
];

const App = () => {
  const [list, setList] = useState(items);

  const onDragEnd = (result) => {
    if (!result.destination) return;
    const newList = Array.from(list);
    const [removed] = newList.splice(result.source.index, 1);
    newList.splice(result.destination.index, 0, removed);
    setList(newList);
  };

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="droppable">
        {(provided) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            {list.map((item, index) => (
              <Draggable key={item.id} draggableId={item.id} index={index}>
                {(provided) => (
                  <div
                    ref={provided.innerRef}
                    {...provided.draggableProps}
                    {...provided.dragHandleProps}
                  >
                    {item.content}
                  </div>
                )}
              </Draggable>
            ))}
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};

使用原生 HTML5 API

适合简单场景,无需额外依赖。

实现示例:

react如何实现拖拽布局

const DraggableComponent = () => {
  const handleDragStart = (e) => {
    e.dataTransfer.setData('text/plain', e.target.id);
  };

  const handleDrop = (e) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text');
    const draggable = document.getElementById(id);
    e.target.appendChild(draggable);
  };

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

  return (
    <div>
      <div
        id="drag-item"
        draggable
        onDragStart={handleDragStart}
        style={{ width: '100px', height: '100px', background: 'red' }}
      />
      <div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        style={{ width: '200px', height: '200px', border: '1px dashed black' }}
      />
    </div>
  );
};

性能优化建议

  • 对于大型列表,使用 react-windowreact-virtualized 进行虚拟滚动
  • 避免在拖拽过程中频繁更新状态
  • 使用 CSS transform 代替 top/left 定位以减少重排

选择依据

  • 简单拖放:原生 HTML5 API
  • 列表排序:react-beautiful-dnd
  • 复杂交互:react-dnd
  • 跨框架需求:dnd-kit(较新的替代方案)

分享给朋友:

相关文章

vue实现动态显示布局

vue实现动态显示布局

Vue 动态显示布局的实现方法 使用 v-if 和 v-show 控制元素显示 v-if 和 v-show 是 Vue 中常用的指令,用于动态控制元素的显示和隐藏。v-if 是条件渲染,当条件为 fa…

vue实现上下布局

vue实现上下布局

实现上下布局的基本结构 在Vue中实现上下布局,可以通过CSS Flexbox或Grid布局快速完成。以下是一个基础模板示例: <template> <div class="l…

vue如何实现放大缩小

vue如何实现放大缩小

Vue 实现放大缩小功能 在 Vue 中实现放大缩小功能可以通过多种方式实现,以下介绍几种常见的方法: 使用 CSS transform 缩放 通过绑定 CSS 的 transform: scale…

权限管理vue如何实现

权限管理vue如何实现

基于路由的权限控制 在Vue中可以通过路由守卫实现页面级权限控制。定义路由时添加meta字段标记权限角色: const routes = [ { path: '/admin',…

h5如何实现定位

h5如何实现定位

使用HTML5 Geolocation API HTML5提供了Geolocation API,可以获取用户的地理位置信息。通过navigator.geolocation对象实现,支持获取经纬度、海拔…

vue如何实现计算

vue如何实现计算

Vue 计算属性的实现方法 在 Vue 中,计算属性(computed properties)是一种基于响应式依赖进行缓存的属性,适用于处理复杂逻辑或依赖其他数据属性的场景。以下是实现计算属性的几种方…