当前位置: 首页 > news >正文

【dnd-kit】react前端做一个可以垂直拖动的无序列表

背景和效果

需要做一个垂直拖动的无序列表。因项目中其他模块已经使用了dnd-kit, 为保持一致,使用的也是dnd-kit。效果如下:

可拖拽列表示例

资料

React生态中主流拖拽库的深度对比与选型指南

选型决策矩阵

代码

importReact,{useState}from'react';import{DndContext,closestCenter,PointerSensor,useSensor}from'@dnd-kit/core';import{SortableContext,verticalListSortingStrategy,useSortable}from'@dnd-kit/sortable';import{CSS}from'@dnd-kit/utilities';constmockData=[{id:"1",name:"项目一"},{id:"2",name:"项目二"},{id:"3",name:"项目三"},{id:"4",name:"项目四"},{id:"5",name:"项目五"},{id:"6",name:"项目六"},]constDragableList=()=>{const[items,setItems]=useState(mockData);constsensor=useSensor(PointerSensor,{activationConstraint:{distance:5,},});// 可排序列表项组件constSortableItem=({item})=>{const{attributes,listeners,setNodeRef,transform,transition,isDragging,}=useSortable({id:item.id});conststyle={transform:CSS.Transform.toString(transform),// 决定拖拽效果transition,opacity:isDragging?0.5:1,cursor:'grab',padding:'12px',margin:'8px 0',backgroundColor:'#f8f9fa',border:'1px solid #dee2e6',borderRadius:'4px',userSelect:'none',};return(<div ref={setNodeRef}style={style}{...attributes}{...listeners}>// 如果拖拽的模块更复杂,写在这个return里{item.name}</div>);};consthandleDragEnd=(event)=>{const{active,over}=event;if(active.id!==over?.id){setItems((items)=>{constoldIndex=items.findIndex(item=>item.id===active.id);constnewIndex=items.findIndex(item=>item.id===over.id);// 重新排列数组constnewItems=[...items];const[movedItem]=newItems.splice(oldIndex,1);newItems.splice(newIndex,0,movedItem);returnnewItems;});}};return(<div style={{padding:'20px',maxWidth:'400px',margin:'0 auto'}}><h2>可拖拽列表</h2><DndContext sensors={[sensor]}collisionDetection={closestCenter}onDragEnd={handleDragEnd}><SortableContext items={items.map((item)=>item.id)}strategy={verticalListSortingStrategy}>{items.map((item)=>(<SortableItem key={item.id}item={item}/>))}</SortableContext></DndContext><div style={{marginTop:'20px',fontSize:'14px',color:'#6c757d'}}><p>拖拽说明:</p><ul><li>点击并拖动项目可重新排序</li><li>当前项目数:{items.length}</li></ul></div></div>);};exportdefaultDragableList;

复杂组件

// 可排序列表项组件constSortableItem=({item})=>{const{attributes,listeners,setNodeRef,transform,transition,isDragging,}=useSortable({id:item.id});conststyle={transform:CSS.Transform.toString(transform),// 决定拖拽效果transition,opacity:isDragging?0.5:1,cursor:'grab',padding:'12px',margin:'8px 0',backgroundColor:'#f8f9fa',border:'1px solid #dee2e6',borderRadius:'4px',userSelect:'none',};return(<div ref={setNodeRef}style={style}{...attributes}{...listeners}><Tooltip><Popconfirm title="确定删除这条属性吗?"onConfirm={()=>deleteAttr()}conCancel={(e)=>{console.log(e)}}><Button>删除</Button></Popconfirm></Tooltip></div>);};
http://www.gsyq.cn/news/1631671.html

相关文章:

  • 计算机毕业设计之基于jsp考研在线复习平台
  • Gemini Advanced订阅价值评估与合规使用指南
  • 从零到一:raylib游戏开发库终极入门指南
  • 终极指南:如何用yuzu模拟器在PC上流畅玩转任天堂Switch游戏
  • 5步打造专属漫画浏览体验:E-Viewer高效使用指南
  • 基建配套预制构件怎么选?2026年7月预制检查井厂家推荐参考
  • 百度文库文档净化脚本:让PDF保存变得简单纯粹
  • 解决方案:如何5分钟构建企业级国标视频监控平台
  • 如何免费提升BT下载速度300%:trackerslist终极指南
  • Qwen3实测全解析:4B到32B模型在多平台部署与中文任务表现
  • 特征融合技术提升小目标检测性能:原理、实现与工程实践
  • STM32F103C8T6的USB—CDC虚拟端口组件(HAL)
  • 《大模型实战指南》—— 面向软件开发者的系统性入门2
  • AI开发环境本地化:Codex与DeepSeek的协议转换与代理部署实战
  • 普通人也能入场的3个高薪AI岗位,平均月薪超3万!AI时代的机会在这里!
  • 【YOLOv8多模态融合改进】| TGRS 2025 HFFE分层特征融合编码器 双模态注意力加权 + 跨尺度对齐融合,强化弱小目标多模态特征互补
  • Deepseek-V4与Claude-Opus-4.7编程实战对比:谁更懂中国开发者
  • 基于微信小程序的原生开发流程实践——从0到可用
  • E-Hentai漫画批量下载:告别手动保存的高效归档方案
  • Linux gzip 命令实战:从基础压缩到高效归档
  • Windows平台Appium 2.0自动化测试环境搭建与真机连接实战指南
  • C#嵌入x86汇编——一个GPIO接口的实现
  • SVN简单使用教程
  • 深度实战:Hindsight AI代理内存系统的7个高效性能调优策略
  • 【Linux网络编程】传输层协议TCP
  • Java计算机毕设之智能化商超收银折扣核算管理系统的设计与实现 基于 SpringBoot 的商场动态折扣更新管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 【电脑操作】C盘清理操作
  • [LangChain中的Multi-Agent模式-03]Handoffs:状态驱动的多阶段流程编排与状态机管理
  • 解决Kivy中文乱码问题:从方块乱码到完美显示
  • E-Hentai Downloader:高效漫画批量下载工具的全方位应用指南