三级分类拖拽修改、批量修改、删除
拖拽修改(页面效果)
页面效果
首先设置el-tree的属性
:draggable=“draggable”
可拖拽效果绑定变量
:allow-drop=“allowDrop”
是否可以拖拽后放置定义方法绑定
@node-drop=“handleDrop”
拖拽放置后调用方法
ref=“menuTree”
绑定tree组件获取checkbox选中元素
<el-tree
:data="menus"
node-key="catId"
:props="defaultProps"
@node-click="handleNodeClick"
show-checkbox
:expand-on-click-node="false"
:draggable="draggable"
:allow-drop="allowDrop"
@node-drop="handleDrop"
ref="menuTree"
:default-expanded-keys="expandedKey"
>
数据收集
在data中绑定数据
data() {
//这里存放数据
return {
pCid: [],
draggable: true,
updateNodes: [],
maxLevel: 0,
dialogVisible: false, //弹框不显示
dialogType: "",
title: "",
category: {
catId: null,
name: "",
parentcid: 0,
catLevel: 0,
showStatus: 1,
sort: 0,
icon: "",
productunit: "",
productCount: 0,
},
menus: [],
expandedKey: [],
defaultProps: {
children: "child",
label: "name",
},
};
},
写好数据收集方法
//是否可以被拖拽后放置
allowDrop(draggingNode, dropNode, type) {
//1、被拖动的当前节点以及所在的父节点总层数不能大于3
//1)、被拖动的当前节点总层数
console.log("allowDrop:", draggingNode, dropNode, type);
//
this.countNodeLevel(draggingNode);
//当前正在拖动的节点+父节点所在的深度不大于3即可
let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;
console.log("深度:", deep);
// this.maxLevel
if (type == "inner") {
// console.log(
// `this.maxLevel:${this.maxLevel};draggingNode.data.catLevel:${draggingNode.data.catLevel};dropNode.level:${dropNode.level}`
// );
return deep + dropNode.level <= 3;
} else {
return deep + dropNode.parent.level <= 3;
}
},
//拖拽后调用方法
handleDrop(draggingNode, dropNode, dropType, ev) {
console.log("handleDrop: ", draggingNode, dropNode, dropType);
//1、当前节点最新的父节点id
let pCid = 0;
let siblings = null;
if (dropType == "before" || dropType == "after") {
pCid =
dropNode.parent.data.catId == undefined
? 0
: dropNode.parent.data.catId;
siblings = dropNode.parent.childNodes;
} else {
pCid = dropNode.data.catId;
siblings = dropNode.childNodes;
}
this.pCid.push(pCid);
//2、当前拖拽节点的最新顺序,
for (let i = 0; i < siblings.length; i++) {
if (siblings[i].data.catId == draggingNode.data.catId) {
//如果遍历的是当前正在拖拽的节点
let catLevel = draggingNode.level;
if (siblings[i].level != draggingNode.level) {
//当前节点的层级发生变化
catLevel = siblings[i].level;
//修改他子节点的层级
this.updateChildNodeLevel(siblings[i]);
}
this.updateNodes.push({
catId: siblings[i].data.catId,
sort: i,
parentCid: pCid,
catLevel: catLevel,
});
} else {
this.updateNodes.push({ catId: siblings[i].data.catId, sort: i });
}
}
//3、当前拖拽节点的最新层级
console.log("updateNodes", this.updateNodes);
},
// 递归调用修改子节点层级
updateChildNodeLevel(node) {
if (node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
var cNode = node.childNodes[i].data;
this.updateNodes.push({
catId: cNode.catId,
catLevel: node.childNodes[i].level
});
this.updateChildNodeLevel(node.childNodes[i]);
}
}
},
//递归查询当前拖拽节点的层级
countNodeLevel(node) {
//找到所有子节点,求出最大深度
if (node.childNodes != null && node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].level > this.maxLevel) {
this.maxLevel = node.childNodes[i].level;
}
this.countNodeLevel(node.childNodes[i]);
}
}
},
批量修改(数据交互)
前面已经实现了拖动的页面效果,现在批量修改需要将可拖拽效果绑定到switch开关上
修改数据datas属性
draggable: false,
添加switch组件和批量修改按钮
<template>
<div>
<el-switch v-model="draggable" active-text="开启拖拽" inactive-text="关闭拖拽"></el-switch>
<el-button v-if="draggable" @click="batchSave">批量保存</el-button>
前端数据传输
添加保存方法
batchSave() {
this.$http({
url: this.$http.adornUrl("/product/category/update/sort"),
method: "post",
data: this.$http.adornData(this.updateNodes, false),
}).then(({ data }) => {
this.$message({
message: "菜单顺序等修改成功",
type: "success",
});
//刷新出新的菜单
this.getMenus();
//设置需要默认展开的菜单
this.expandedKey = this.pCid;
this.updateNodes = [];
this.maxLevel = 0;
// this.pCid = 0;
});
},
后台代码修改
这里前端传过来的是一个json对象数组
我们在product里面编写一个批量修改方法
categoryController.java
/**
* 修改
*/
@RequestMapping("/update/sort")
public R updateSort(@RequestBody List<CategoryEntity> updateNodes){
categoryService.updateBatchById(updateNodes);
return R.ok();
}
批量删除
页面加上批量删除按钮
<el-button type="danger" @click="batchDelete">批量删除</el-button>
调用方法
batchDelete() {
let catIds = [];
let checkedNodes = this.$refs.menuTree.getCheckedNodes();
console.log("被选中的元素", checkedNodes);
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}) => {
this.$message({
message: "菜单批量删除成功",
type: "success"
});
this.getDataList();
});
})
.catch(() => {
});
},