这里博主主要是使用的H5原生拖拽方式,更多的拖拽方式实现:react-beautiful-dnd、react-dnd、react-grid-layout等等。
一、实现思路
使用变量临时存储当前拖拽对象和需要交换位置的对象,然后通过函数方法动态改变数组中所要交换的对象,最后得到拖拽后的新数组,实现拖拽排序。
二、具体代码
1、主体部分(index.tsx)
这里使用的是TypeScript
import React, { useState, useEffect } from 'react';
import { Row, Col } from 'antd';
import './index.less';
const Sort: React.FunctionComponent = () => {
/* 随机生成应用列表 */
const getAppList = () => {
const tempArr: any[] = [];
for (let index = 1; index < 10; index++) {
tempArr.push({
id: index,
name: `应用${index}`,
backgroundColor: getRandomColor(),
});
}
return tempArr;
};
/* 随机生成背景颜色 */
const getRandomColor = () => {
let letter = `0123456789ABCDEF`;
let color = '#';
for (let i = 0; i < 6; i++) {
color += letter[Math.floor(Math.random() * 16)];
}
return color;
};
// 应用列表
const [list, setList] = useState<any[]>([]);
// 当前拖拽对象
const [oldDragItem, setOldDrageItem] = useState<any>();
// 拖拽交换对象
const [newDragItem, setNewDragItem] = useState<any>();
// 是否拖拽进行
const [isEnter, setIsEnter] = useState<any>();
// 是否拖拽
const [isActive, setIsActive] = useState<any>();
/* 拖拽开始 */
const onDragStart = (value: any) => {
setOldDrageItem(value);
setIsActive(value.id);
};
/* 拖拽进行 */
const onDragEnter = (value: any) => {
setIsEnter(value.id);
setNewDragItem(value);
};
/* 拖拽结束 */
const onDragEnd = () => {
if (oldDragItem != newDragItem) {
const oldIndex = list.indexOf(oldDragItem); //获取当前对象所在数组坐标
const newIndex = list.indexOf(newDragItem); //获取当前目标对象所在数组坐标
const newArray = [...list];
newArray.splice(oldIndex, 1); //删除老节点
newArray.splice(newIndex, 0, oldDragItem); //增加新节点
setList(newArray); //保存拖拽后的数组
setIsActive(-1); //重置状态
setIsEnter(-1);
}
};
useEffect(() => {
document.addEventListener('dragover', function (event) {
//阻止事件的默认行为
event.preventDefault();
//设置拖拽时鼠标样式
event.dataTransfer.dropEffect = 'move';
});
// 赋值列表
setList(getAppList());
}, []);
return (
<Row className="list">
{list?.map((item: any) => (
<Col
style={{
backgroundColor: item.backgroundColor,
}}
className={
oldDragItem == item && isActive == item.id
? 'active item'
: newDragItem == item && isEnter == item.id
? 'enter item'
: 'item'
}
key={item.id}
draggable={true}
onDragStart={() => {
onDragStart(item);
}}
onDragEnter={() => {
onDragEnter(item);
}}
onDragEnd={() => {
onDragEnd();
}}
>
{item.name}
</Col>
))}
</Row>
);
};
export default Sort;
2、样式部分(index.less)
.list {
.item {
display: flex;
justify-content: center;
align-items: center;
height: 100px;
width: 100px;
color: white;
font-weight: 600;
}
.focus {
cursor: pointer;
}
.item:hover {
transition-duration: 0.3s;
transform: scale(1.05);
}
.active {
cursor: pointer !important;
}
.enter {
cursor: pointer !important;
opacity: 0.3;
box-shadow: 1px 1px 10px 1px rgba(0, 0, 0, 0.1) inset;
}
}
三、效果运行图
通过改变布局,实现不同的拖拽排序
1、横向拖拽排序
2、纵向拖拽排序
3、宫格拖拽排序