react项目拖拽排序,本想搞一搞 dnd插件等生态,奈何项目太老 版本太低,参考网上的手写 做了一个组件。
import React from 'react';
import {Icon} from 'antd';
import styles from './index.less';
export default class List extends React.Component {
dragStart(e) {
this.dragged = e.currentTarget;
}
dragEnd(e) {
this.dragged.style.display = 'flex';
e.target.classList.remove('drag-up');
this.over.classList.remove('drag-up');
e.target.classList.remove('drag-down');
this.over.classList.remove('drag-down');
var data = this.props.data;
var from = Number(this.dragged.dataset.id);
var to = Number(this.over.dataset.id);
data.splice(to, 0, data.splice(from, 1)[0]);
//set newIndex to judge direction of drag and drop
data = data.map((doc, index) => {
doc.newIndex = index + 1;
return doc;
});
this.props.sorted(data);
}
dragOver(e) {
e.preventDefault();
this.dragged.style.display = 'none';
if (e.target.tagName !== 'LI') {
return;
}
//判断当前拖拽target 和 经过的target 的 newIndex
const dgIndex = JSON.parse(this.dragged.dataset.item).newIndex;
const taIndex = JSON.parse(e.target.dataset.item).newIndex;
const animateName = dgIndex > taIndex ? 'drag-up' : 'drag-down';
if (this.over && e.target.dataset.item !== this.over.dataset.item) {
this.over.classList.remove('drag-up', 'drag-down');
}
if (!e.target.classList.contains(animateName)) {
e.target.classList.add(animateName);
this.over = e.target;
}
}
render() {
var listItems = this.props.data.map((item, i) => {
return (
<li
data-id={i}
key={i}
className={styles.list}
draggable="true"
onDragEnd={this.dragEnd.bind(this)}
onDragStart={this.dragStart.bind(this)}
data-item={JSON.stringify({...item, newIndex: i})}
>
{item.name}
{!this.props.disabled ? (
<Icon
type="close"
onClick={() => this.props.onCloseTag(item.id)}
></Icon>
) : null}
</li>
);
});
return (
<ul onDragOver={this.dragOver.bind(this)} style={{padding: 0}}>
{listItems}
</ul>
);
}
}
.list{
user-select: none;
padding: 0px 10px;
border-radius: 4px;
display: flex;
justify-content: space-between;
border: 1px solid #d8d8d8;
align-items: center;
margin-bottom: 5px;
}
需要注意的地方
- 因为是排序,所以传进来的值需要在排序后更新。
- 选择后进行拖拽排序,这样要保证选中的值是按当前的顺序进行排序