最近有個需求, 需要實現(xiàn)一下拖拽排序, 不需要動畫, 能實現(xiàn)功能即可. 現(xiàn)有的類庫就不太想集成, 自己手擼一下, 實現(xiàn)即可.
1. 首先設(shè)置state
constructor(props) {
super(props);
this.state = {
dataArray: [],
dragElement: null,
lock: true,
};
}
這個dataArray就是我們的數(shù)據(jù)源
2. 在componentDidMount
中阻止一下dragover和drop的默認行為
componentDidMount() {
document.addEventListener('dragover', this.preventDefault);
document.addEventListener('drop', this.preventDefault);
}
這里的this.preventDefault方法是我自己封裝了一下的
preventDefault = (e) => { e.preventDefault(); }
3. 在componentWillUnmount
中刪除監(jiān)聽器
componentWillUnmount() {
document.removeEventListener('dragover', this.preventDefault);
document.removeEventListener('drop', this.preventDefault);
}
4. 給要排序的元素實現(xiàn)如下屬性
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>
);
}