看了
首先创建一个树
<template>
<Tree
:tree-data="treeData"
v-model:expandedKeys="expandedKeys" // 展开的节点
:auto-expand-parent="true" // 是否自动展开节点
block-node
draggable // 设置节点可拖拽 必备
@drop="onDrop" // 拖拽后触发
/>
</template>
<script lang="ts" setup>
... 省略其他代码
// 整理树结构
function createTreeData() {
const data: any[] = [];
// AllData = 总数据,不带结构的树控件数据
AllData.forEach((data) => {
// 判断是否是父节点 也可以是其他的参数进行判断
if (!data.pid) {
const node: any = {
index: data.order,
isLeaf: false,
title: data.title,
key: data.id,
id: data.id,
pId: data.pid,
show: data.show,
raw: cloneDeep(toRaw(data)),
};
node.children = findChild(node, AllData);
data.push(node);
}
});
treeData.value = data;// 有结构的树控件
}
// 添加节点下的数据
function findChild(parent: any, list: any[]) {
return list
.filter((item: any) => item.pid === parent.id)
.map((item: any) => {
let node: any;
if (item.pid) {
node = {
index: item.order,
isLeaf: false,
title: item.title,
key: item.id,
id: item.id,
pId: item.pid,
show: item.show,
raw: cloneDeep(toRaw(item)),
};
node.children = findChild(node, list);
} else {
node = {
index: item.order,
title: item.title,
key: item.id,
id: item.id,
pId: parent.pid,
parent: parent,
show: item.show,
};
expandedKeys.value.push(node.key);
}
return node;
});
}
</script>
思路: 我们有treeData(有结构的树控件数据)和 AllData(没有结构的数据),拖拽之后修改AllData,在重构树结构就行
树结构整理完成,现在进行拖拽操作onDrop
/*
* 移动节点至另一个大节点下
*
* info.dragNode 被移动的小节点
* info.dragNodesKeys 被移动的小节点 key数组;若是目录,则是该目录下的所有数据的key
* info.dropPosition 被移动的小节点所处的位置
* info.node 移动之后被迫更改的节点(上一个节点) 有数据就是数据,没有数据就是目录
* node.children -- 目录;node.parent -- 数据
* info.dropToGap {boolean} 是否拖拽在数据的下一个位置
*/
const onDrop = async (info: AntTreeNodeDropEvent) => {
const dragNode = info.dragNode;
const node = info.node;
const dropPos = info.node.pos!.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const orderPara = {
dragId: dragNode.id, // 拖拽节点
targetParentId: '', // 目标父节点
targetPrevId: '', // 目标前一个节点
};
// 没有要求的可以不需要
if (!dragNode.children && dropPosition === -1) {
// 数据不能目录
return;
} else if (dropPosition === 0 && !node.children) {
// 数据放在另一个数据之下
return;
}
// 处于同个目录的文件下或者处于目录下的第一个
if (node.children) {
// 文件夹未展开,添加到父节点
if (!info.node.expanded) {
orderPara.targetParentId = node.pId;
orderPara.targetPrevId = node.id;
} else {
orderPara.targetParentId = node.id;
}
}
// 位于数据的下面 与 info.dropToGap = true 一致
if (node.parent) {
orderPara.targetParentId = node.parent.id;
orderPara.targetPrevId = node.id;
}
// 最上面的父节点
if (dropPosition === -1) {
orderPara.targetParentId = '';
}
if (orderPara.targetParentId === '-1') {
orderPara.targetParentId = '';
}
if (orderPara.targetPrevId === '1') {
orderPara.targetPrevId = '';
}
AllData
.filter((data) => data.id === orderPara.dragId)
.map((data) => {
data.pid = orderPara.targetParentId;
const removeI = AllData.findIndex((item) => {
return item.id === orderPara.dragId;
});
AllData.splice(removeI, 1);
// 兄节点
if (orderPara.targetPrevId) {
const addI = AllData.findIndex((item) => {
return item.id === orderPara.targetPrevId;
});
AllData.splice(addI + 1, 0, data);
} else {
AllData.unshift(layer);
}
return layer;
});
createTreeData(); // 重构树结构
};
未解决的问题:
当拖到父目录下的子目录下面的时候,它仅仅只能通过expanded(该目录是否展开)去进行判断,他是拖拽到父目录下还是子目录下的
比如子目录没有展开,即使拖到子目录下,但还是添加到了父目录下;
子目录展开的话,即使拖到父目录下,但是它的上一个节点是展开的子目录,他默认是添加到展开的子目录里面的;
看了官网,也是这样;不知道大佬们有么有其他的解决方法呢?