最近有个需求, 需要实现一下拖拽排序, 不需要动画, 能实现功能即可. 现有的类库就不太想集成, 自己手撸一下, 实现即可.
1. 首先设置state
constructor(props) {
super(props);
this.state = {
dataArray: [],
dragElement: null,
lock: true,
};
}
这个dataArray就是我们的数据源
2. 在componentDidMount
中阻止一下dragover和drop的默认行为
componentDidMount() {
document.addEventListener('dragover', this.preventDefault);
document.addEventListener('drop', this.preventDefault);
}
这里的this.preventDefault方法是我自己封装了一下的
preventDefault = (e) => { e.preventDefault(); }
3. 在componentWillUnmount
中删除监听器
componentWillUnmount() {
document.removeEventListener('dragover', this.preventDefault);
document.removeEventListener('drop', this.preventDefault);
}
4. 给要排序的元素实现如下属性
sortableCard = (sortableInfo) => {
const { id } = sortableInfo;
}
return (
<div
key={id}
draggable
onDragStart={() => {
this.setState({
dragElement: sortableInfo,
});
}}
onDragEnd={(e) => {
e.preventDefault();
}}
onDragEnter={() => {
if (id !== this.state.dragElement.id) {
const oldDragIndex = _.findIndex(this.state.dataArray, item => item.id === this.state.dragElement.id);
const oldEnterIndex = _.findIndex(this.state.dataArray, item => item.id === sortableInfo.id);
if (oldDragIndex > oldEnterIndex) {
const newDataArray= this.state.dataArray.filter(item => item.id !== this.state.dragElement.id);
const insertIndex = _.findIndex(newDataArray, item => item.id === sortableInfo.id);
newDataArray.splice(insertIndex, 0, this.state.dragElement);
this.setState({ dataArray: newDataArray });
} else {
const newDataArray = this.state.dataArray.filter(item => item.id !== this.state.dragElement.id);
const insertIndex = _.findIndex(newDataArray, item => item.Id === sortableInfo.id) + 1;
newDataArray.splice(insertIndex, 0, this.state.dragElement);
this.setState({ dataArray: newDataArray });
}
this.setState({
isConfigDirty: true,
});
}
}}
onDragLeave={() => {
if (sortableInfo.id !== this.state.dragElement.id) {
if (this.state.lock && sortableInfo.id === this.state.dataArray[this.state.dataArray.length - 1]) {
const newDataArray = this.state.dataArray.filter(item => item.id !== this.state.dragElement.id);
newDataArray.push(this.state.dragElement);
this.setState({
lock: false,
}, () => {
this.setState({
dataArray: newDataArray,
});
});
} else {
this.setState({
lock: true,
});
}
}
}}
>
<div>你的东西</div>
</div>
);
}