实现表格行上下拖拽移动功能需求求助
表格行拖拽移动实现方案
需求:给五列表格添加行上下拖拽调整位置的功能,要求用户悬停在某一行时,第一列的拖拽按钮显示,点击该按钮可拖动该行进行上下位置调整。
以下是基于React的原生实现方案,无需依赖第三方拖拽库:
实现步骤
- 状态管理:维护表格数据数组,以及拖拽过程中的临时状态(当前拖拽行索引、拖拽中状态)
- 鼠标事件处理:实现拖拽开始、拖拽中、拖拽结束的逻辑,通过数组元素交换完成行位置调整
- 样式优化:添加拖拽过程中的视觉反馈,提升用户操作感知
完整代码实现
import { useState } from 'react'; import AppsIcon from '@mui/icons-material/Apps'; export default function App() { // 示例数据,替换为你的实际业务数据 const [nodes, setNodes] = useState([ { name: '行1', length: 10, hotkey: 'Ctrl+A', isActivness: true }, { name: '行2', length: 20, hotkey: 'Ctrl+B', isActivness: false }, { name: '行3', length: 15, hotkey: 'Ctrl+C', isActivness: true }, { name: '行4', length: 5, hotkey: 'Ctrl+D', isActivness: false }, ]); const [draggingIndex, setDraggingIndex] = useState(null); const [hoverIndex, setHoverIndex] = useState(null); // 触发拖拽,记录当前拖拽行索引 const handleDragStart = (index) => { setDraggingIndex(index); }; // 拖拽过程中,实时交换行位置 const handleDragOver = (e, index) => { e.preventDefault(); if (draggingIndex === index) return; const newNodes = [...nodes]; // 交换拖拽行与当前悬停行的位置 const draggedItem = newNodes[draggingIndex]; newNodes.splice(draggingIndex, 1); newNodes.splice(index, 0, draggedItem); setNodes(newNodes); setDraggingIndex(index); setHoverIndex(index); }; // 结束拖拽,清空临时状态 const handleDragEnd = () => { setDraggingIndex(null); setHoverIndex(null); }; return ( <table className="zui"> <tbody style={{ fontSize: "40px" }}> {nodes.map((val, key) => ( <tr key={key} className={hoverIndex === key ? 'drag-hover' : ''} > <td> <AppsIcon className="sss" draggable onDragStart={() => handleDragStart(key)} onDragOver={(e) => handleDragOver(e, key)} onDragEnd={handleDragEnd} style={{ cursor: draggingIndex === key ? 'grabbing' : 'grab' }} /> </td> <td style={{ paddingLeft: "20px" }}> {val.name} </td> <td>{val.length}</td> <td>{val.hotkey}</td> <td>{val.isActivness ? '激活' : '未激活'}</td> </tr> ))} </tbody> </table> ); }
更新后的样式(styles.css)
.sss { visibility: hidden; transition: visibility 0.2s ease; } tr:hover .sss { visibility: visible; } tr:hover { background-color: #f0f0f0; } /* 拖拽悬停行的高亮样式 */ tr.drag-hover { background-color: #e0e0e0; } td:first-child { border-top-left-radius: 5px; border-bottom-left-radius: 5px; } td:last-child { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
核心逻辑说明
- 仅给第一列的拖拽图标开启
draggable属性,避免整行误触发拖拽 - 在
onDragOver事件中实时交换数组元素位置,实现拖拽过程中行位置的即时更新 - 通过
drag-hover类和图标光标变化,提供清晰的拖拽状态反馈
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

