之前做项目有遇到过使用el-tree的,但是树形结构拖拽还是第一次遇到,开始觉得会好难(心里暗示),因为考虑到好多种情况,做完之后其实还好,在此记录一下~
首先,树形结构的拖拽---
<el-tree
v-model="filterText"//过滤
class="tree"
:data="projectNameOptions"
node-key="id"
:props="chapterProps"
default-expand-all//默认展开所有节点
:filter-node-method="filterNode"
ref="projectNameOptions"
draggable//是否开启拖拽节点功能,默认为false
@node-drop="handleDrop"//拖拽完成时触发的事件
//共四个参数,依次为:被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置(before、after、inner)、event
>
其实,只需要一个属性即可:
前端拖拽一个属性就搞定了,so easy,接下来就是让人头疼的地方了,前端拖拽之后我们需要持久化到数据库呀,不然拖拽只是前端的一个动画效果而已。为什么说是让人头疼的地方呢,因为当时考虑了好多好多种情况,整个人脑子都要炸了,感激这位网友的这篇博客真的是救了我一命=ElementUI El-Tree 任意拖拽排序方法,最小粒度数据变更范围(通用排序)_小狐狸和小兔子-CSDN博客_eltree拖拽排序实现思路
详情如下:
// 拖拽完成时触发的事件 参数依次为:被拖拽节点、结束拖拽时最后进入的节点、被拖拽节点的放置位置(before、after、inner)、event
//注意:目标节点是已经移动完之后的节点
handleDrop: async function(draggingNode, dropNode, dropType, ev) {
//定义一个空数组用于存放需要持久化到数据库的节点
var paramData = [];
//当拖拽类型不为inner,说明只是在现有的节点间移动,只需要寻找目标节点的父ID,获取其对象以及所有的子节点,data为目标节点的父节点;
//否则,当拖拽类型为inner,说明拖拽节点成为了目标节点的子节点,只需要获取目标节点对象即可,data为目标节点
var data = dropType != "inner" ? dropNode.parent.data : dropNode.data;
//目标节点的level==1即目标节点为一级节点,
//并且拖拽类型不为inner即当前节点将成为与目标节点同一层级的节点,也是一级节点
//nodeDate=data,通过上面的公式data=dropNode.parent.data,因此,nodeData=dropNode.parent.data,但是因为目标节点已经是一级节点了,因此,nodeData还是目标节点
//否则
//目标节点的level==1即目标节点为一级节点,
//并且拖拽类型为inner即当前节点将成为目标节点的子节点即二级节点
//nodeDate=data.childrens,通过上面的公式data=dropNode.parent.data,因此,nodeData=dropNode.parent.data.childrens,即为目标节点的父节点的子节点,即目标节点同一层级的节点
//或者
//目标节点的level!=1即目标节点不是一级节点,
//并且拖拽类型不为inner即当前节点将成为与目标节点同一层级的节点
//nodeDate=data.childrens,通过上面的公式data=dropNode.parent.data,因此,nodeData=dropNode.parent.data.childrens,即为目标节点的父节点的子节点,即目标节点同一层级的节点
//或者
//目标节点的level!=1即目标节点不是一级节点
//并且拖拽类型为inner即当前节点将成为目标节的子节点,通过上面的公式
//nodeDate=data.childrens,通过上面的公式data=dropNode.data,因此,nodeData=dropNode.data.childrens,即目标节点的子节点
//定义要循环的节点
var nodeData = dropNode.level == 1 && dropType != "inner" ? data : data.childrens;
nodeData.forEach(element=>{
//设置父ID,当目标节点level为1说明在第一层,父ID为空;
//否则,父id为data.id
//当拖拽类型不为inner时,element.parentId=data.id=dropNode.parent.data.id即目标节点的父节点的id
//当拖拽类型为inner时,element.parentId=data.id=dropNode.data.id即目标节点的id
element.parentId = dropNode.level == 1 ? "" : data.id;
});
var pri=1
nodeData.forEach((element, i) => {
//当拖拽类型不为inner,为before或after时,说明只是在目前已有的层级间移动
//只需要寻找目标节点的parentId,即为当前节点的parentId
// 与目标节点的同一层级的节点的priority按照现在的排列顺序重新排列1++
var dept = {
id: element.id,
parentId: element.parentId,
priority:pri++,
projectName:element.projectName
};
paramData.push(dept);
});
updateProject(paramData).then((res) => {
console.log(res);
if (res.code == '200') {
this.$message({
message: '更新成功',
type: 'success'
});
paramData={}
}else{
this.$message({
message: '更新失败',
type: 'error'
});
}
})
},
看到上面的注释太多可能容易让人不想看,觉得太复杂,小编整理了一个思维导图的形式:
总结:不要给自己设限,不要在没有做一件事之前做假设,干就完了!!!