【成果展示】:
【快速回顾】:
元素在完成拖拽后,数据库中的相关层级、各个元素的排列顺序并没有进行保存,需要连接后端保存到数据库中。
为了防止拖拽的误操作,我们需要设置一个按钮来控制拖拽功能的开启与关闭 (使用el-switch组件来完成这个功能);
【减少前后端频繁交互】:
拖一次就更新一次的话是没有必要的 ,可以拖完之后一次性和后端交互。统一把数据提交到后端。
【批量删除】:
之前只在叶子节点上设置了删除按钮 , 叶子节点往上更高的节点没有设置《删除》按钮 ,在批量删除之前需要进行勾选,一次性删除选中的节点;
【详细内容】:
【拖拽完成时的触发事件】:
<el-tree>标签中:
@node-drop="handleDrop"
【相关函数】:
【拖拽相关代码】:
<el-switch v-model="draggable" active-text="开启拖拽" inactive-text="关闭拖拽">
<el-tree
:draggable="draggable"
>
data() {
return {
draggable:false, //拖拽功能默认是关闭的。
}
}
【相关代码】:
batchDelete(){ //批量删除的方法
let catIds = [];
let checkedNodes= this.$refs.tree.getCheckedNodes( false , false );
for( let i=0 ; i<checkedNodes.length ; i++ ){
catIds.push(checkedNodes[i].catId);
}
this.$confirm(`是否确认删除【${catIds}】记录?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 把删除的请求提交到后台服务
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(catIds, false),
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
});
// 重新加载所有的菜单数据
this.getCategory();
} else {
this.$message.error(data.msg);
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
handleDrop(draggingNode, dropNode, type, event) {
//(1)拖拽节点的父节点需要修改
let parentId = 0;
let siblings = null; //存所有的兄弟节点。
if (type == "inner") {
parentId = dropNode.data.catId;
//找到拖拽节点对应的所有的兄弟节点;
siblings = dropNode.childNodes;
} else {
parentId =
dropNode.parent.data.catId == undefined
? 0
: dropNode.parent.data.catId;
siblings = dropNode.parent.childNodes;
}
//(2)拖拽后节点所在的新的兄弟节点间的排序问题
for (let i = 0; i < siblings.length; i++) {
if (siblings[i].data.catId == draggingNode.data.catId) {
//获取的就是拖拽的那个节点 , 那么我们需要更新parent_cid
//(3)拖拽后的节点及其子节点的 catLevel更新问题
let catLevel = draggingNode.level;
if (siblings[i].level != catLevel) {
//拖拽后节点的层级发生了变化。
catLevel = siblings[i].level;
//递归的方式来更新子节点的层级
this.updateChildNodeLevel(siblings[i]);
}
this.updateNodes.push({
catId: siblings[i].data.catId,
sort: i,
parentCid: parentId,
catLevel: catLevel,
});
} else {
this.updateNodes.push({ catId: siblings[i].data.catId, sort: i });
}
}
//我们需要将拖拽后的数据完整的更新到后端服务当中;
// this.updateSort(parentId); //一次更新的操作 ===》 按钮的点击上
this.pCids.push(parentId)
},
updateSort( ) { //parentId原先是这个方法的参数,因为按钮一键更新的原因撤销掉了。
//批量更新拖拽后的数据,层级 + 排序;
this.$http({
url: this.$http.adornUrl("/product/category/updateBatch"),
method: "post",
data: this.$http.adornData(this.updateNodes, false),
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "数据拖拽成功",
type: "success",
});
//重新加载所有的菜单数据;
this.getCategory();
//设置默认展开的父节点信息;
this.expandKeys = this.pCids;
//重置存储拖拽数据的容器;
this.updateNodes = [];
this.maxLevel = 0;
} else {
this.$message.error(data.msg);
}
});
},
updateChildNodeLevel(node) {
//判断一下有没有子节点
if (node.childNodes != null && node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
var childNode = node.childNodes[i].data;
this.updateNodes.push({
catId: childNodes.catId,
catLevel: node.childNodes[i].level,
});
//如果还有子节点 , 同步的更新处理
this.updateChildNodeLevel(node.childNodes[i]);
}
}
}