<Tree
ref="treeRef"
:treeData="treeData"
draggable // 开启拖动
@drop="onDrop" // 拖动完成的回调
/>
const onDrop = (info: DropEvent) => {
const dropKey = info.node.eventKey;
const dragKey = info.dragNode.eventKey;
const dragPos = info.dragNode.pos.split('-');
const dropPos = info.node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
// console.log('dropKey:', dropKey);
// console.log('dragKey:', dragKey);
// console.log('info:', info);
// console.log('dragPos:', dragPos);
// console.log('dropPos:', dropPos);
// console.log('dropPosition:', dropPosition);
// 层级
const dragLevel = dragPos.length - 1;
const dropLevel = dropPos.length - 1;
const data = [...treeData.value];
// 找到拖动的数组对象
let dragObj: TreeDataItem = {};
findInWhole(data, 'key', dragKey, (item: TreeDataItem, index: number, arr: TreeDataItem[]) => {
arr.splice(index, 1);
dragObj = item;
});
let ar: TreeDataItem[] = [];
let i = 0;
let Id = '';
// 找到拖动的位置
findInWhole(data, 'key', dropKey, (_: TreeDataItem, index: number, arr: TreeDataItem[], parentId) => {
ar = arr;
i = index;
Id = parentId;
});
if (!info.dropToGap) {
// Drop on the content
findInWhole(data, 'key', dropKey, (item: TreeDataItem) => {
item.children = item.children || [];
// where to insert 添加到尾部
item.children.push(dragObj);
});
} else {
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
console.log(ar, Id, '------------');
treeData.value = cloneDeep(data); // 赋值处理好的数据,更新树数据
};
// 递归处理树数据,返回找的拖动节点,和拖动的兄弟节点数组,和拖动的父亲节点的id(可根据需求自己定义)
function findInWhole(list: any[], key = 'name', path: string, callback: any, parentId?: string) {
list.forEach((item, index, arr) => {
if (item[key] === path) {
return callback(item, index, arr, parentId);
}
if (item.children) {
return findInWhole(item.children, key, path, callback, item.id??'');
}
});
}
上述代码就是 AntDesign-vue-Tree组件-拖动排序的代码,当然这个排序完成的结构是需要传递给后端的,具体的形式,可以自行讨论。在代码查找树节点的时候使用了递归查找,所以处理数据量不宜过大,数据量大的需要用户自行判断改变处理算法。核心思想就是把处理好的数据重新赋值。