React 基于antd实现tree同级拖动排序

1,152 阅读1分钟

是关于github大佬们讨论的总结同级拖动排序讨论, 直接看代码codesandbox

import React, { useState } from "react";

import { Tree } from "antd";



const data = [
{

title: "Branch 1",

key: "Branch 1",

children: [

{title: "Branch 1.1",

key: "Branch 1.1"},
{
title: "Branch 1.2",

key: "Branch 1.2"
}]
},
{
title: "Branch 2",
key: "Branch 2",
children: [
{

title: "Branch 2.1",

key: "Branch 2.1"
},
{
title: "Branch 2.2",
key: "Branch 2.2"
}]
},
{
title: "Branch 3",
key: "Branch 3",
children: []
}
];



export default function Demo() {

const [treeData, setTreeData] = useState(data);

const [positions, setPositions] = useState({});



function onDrop(info) {

console.log("info", info);

const dragNode = info.dragNode;

const dropNode = info.node;

console.log(dragNode, dropNode);

const isSameLevel = (a, b) => {

const aLevel = a.props.pos.split("-").length;

const bLevel = b.props.pos.split("-").length;

return aLevel === bLevel;

};



const isSameParent = (a, b) => {

const aLevel = a.props.pos.split("-");

const bLevel = b.props.pos.split("-");

aLevel.pop();

bLevel.pop();

return aLevel.join("") === bLevel.join("");

};



const canDrop =

isSameParent(dragNode, dropNode) &&

isSameLevel(dragNode, dropNode) &&

info.dropToGap;

if (!canDrop) {

return;

}

const sameLevel = isSameLevel(dragNode, dropNode);

const sameParent = isSameParent(dragNode, dropNode);

setPositions({

dragOver: dropNode.dragOver,

dragOverGapBottom: dropNode.dragOverGapBottom,

dragOverGapTop: dropNode.dragOverGapTop,

dropToGap: dropNode.dropToGap

});

console.log("sameLevel", sameLevel);

console.log("sameParent", sameParent);

console.log("info.dropPosition", info.dropPosition);



if (sameParent && sameLevel) {

const dropKey = info.node.props.eventKey;

const dragKey = info.dragNode.props.eventKey;

const dropPos = info.node.props.pos.split("-");

const dropPosition =

info.dropPosition - Number(dropPos[dropPos.length - 1]);


const loop = (data, key, callback) => {

for (let i = 0; i < data.length; i++) {

if (data[i].key === key) {

return callback(data[i], i, data);

}

if (data[i].children) {

loop(data[i].children, key, callback);}}
};

const data = [...treeData];



// Find dragObject

let dragObj;

loop(data, dragKey, (item, index, arr) => {

arr.splice(index, 1);

dragObj = item;

});



if (!info.dropToGap) {

// Drop on the content

loop(data, dropKey, (item) => {

item.children = item.children || [];

// where to insert 示例添加到尾部,可以是随意位置

item.children.push(dragObj);

});

} else if (

(info.node.props.children || []).length > 0 && // Has children

info.node.props.expanded && // Is expanded

dropPosition === 1 // On the bottom gap

) {

loop(data, dropKey, (item) => {

item.children = item.children || [];

// where to insert 示例添加到头部,可以是随意位置

item.children.unshift(dragObj);

})} else {

let ar;

let i;

loop(data, dropKey, (item, index, arr) => {

ar = arr;

i = index;

});

if (dropPosition === -1) {

ar.splice(i, 0, dragObj);

} else {

ar.splice(i + 1, 0, dragObj);
}}



console.log("data", data);

setTreeData(data);
}}

return (

<div>

<div>{JSON.stringify(positions)}</div>

<Tree defaultExpandAll draggable treeData={treeData} onDrop={onDrop} />

</div>

);

}