代码如下
界面效果
界面代码:
<el-button class="comp-tr-top" type="primary" size="small" @click="handleAddTop">添加顶级节点</el-button>
<div class="treenode-container">
<el-tree
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
ref="tree"
class="flow-tree"
default-expand-all
@node-drag-start="handleDragStart"
@node-drag-enter="handleDragEnter"
@node-drag-leave="handleDragLeave"
@node-drag-over="handleDragOver"
@node-drag-end="handleDragEnd"
@node-drop="handleDrop"
draggable
@node-click="handleTreeNodeClick"
>
<template slot-scope="{ node, data }">
<div :id="node.id" class="custom-tree-node">
<template v-if="data.isHead">
<el-input
v-model="data.name"
autofocus
size="mini"
:ref="'slotTreeInputHead'"
@blur.stop="handleHeadAdd(node, data)"
@keyup.enter.native="$event.target.blur()"
></el-input>
</template>
<template v-if="data.isAdd && !data.isHead">
<el-input
v-model="data.name"
autofocus
size="mini"
:ref="'slotTreeInput'+data.parentId"
@blur.stop="handleAdd(node, data)"
@keyup.enter.native="$event.target.blur()"
></el-input>
</template>
<template v-if="node.isEdit">
<el-input
v-model="data.name"
autofocus
size="mini"
:ref="'slotTreeInput'+data.id"
@blur.stop="handleInput(node, data)"
@keyup.enter.native="$event.target.blur()"
></el-input>
</template>
<template v-else>
<span
class="el-tree-icon"
:class="data.children ? node.expanded ? 'el-folder-opened-icon' : 'el-folder-icon' : 'el-document-icon'"
/>
<span>{{ data.name }}</span>
<span v-if="node.isCurrent && !data.isHead && !data.isAdd">
<el-button type="text" size="mini" @click="() => appendTree(node, data)">新增</el-button>
<el-button type="text" size="mini" @click="() => removeTree(node, data)">删除</el-button>
<el-button type="text" size="mini" @click="() => updateTree(node, data)">改名</el-button>
</span>
</template>
</div>
</template>
</el-tree>
</div>
data中定义:
deptOptions: [],
defaultProps: {
children: "children",
label: "name"
},
//是否存在顶级节点的新增
isHeadAdd: false,
initParam: {
// 新增参数
name: "",
isAdd: true,
children: []
},
initParamHead: {
// 新增参数
name: "",
isAdd: true,
isHead: true,
children: [],
parentId : 0, // 父id
parentIds:0
},
//是否新增
isAdd: false,
接口数据:
methods方法
updateTree(_node, _data) {
if (this.isAdd) {
this.$message.error("请完成上次操作后再次点击!");
return;
}
// 设置编辑状态
if (!_node.isEdit) {
this.$set(_node, "isEdit", true);
}
// 输入框聚焦
this.$nextTick(() => {
if (this.$refs["slotTreeInput" + _data.id]) {
this.$refs["slotTreeInput" + _data.id].$refs.input.focus();
}
});
},
handleInput(_node, _data) {
// 修改节点
// 退出编辑状态
if (_node.isEdit) {
if (_data.name && _data.name.length > 0) {
updateFolderTree(_data).then(res => {
if (res.msg === "ok") {
this.isAdd = false;
this.$message({
message: "修改成功",
type: "success"
});
this.$set(_node, "isEdit", false);
this.getTreeselect();
} else {
this.$message({
message: "修改失败",
type: "error"
});
}
});
} else {
this.$message.error("名称不得为空!");
this.isAdd = false;
return;
}
}
},
appendTree(_node, _data) {
if (this.isAdd) {
this.$message.error("请新增完毕后再次点击!");
return;
}
this.isAdd = true;
// 新增节点
// 参数修改
let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
obj.parentId = _data.id; // 父id
obj.parentIds = _data.parentIds + "," + _data.id; // 父id
// 判断字段是否存在
if (!_data.children) {
this.$set(_data, "children", []);
}
// 新增数据
_data.children.push(obj);
this.$nextTick(() => {
if (this.$refs["slotTreeInput" + _data.id]) {
this.$refs["slotTreeInput" + _data.id].$refs.input.focus();
}
});
// 展开节点
if (!_node.expanded) {
_node.expanded = true;
}
},
handleHeadAdd(_node, _data) {
// 修改节点
// 退出编辑状态
if (_data.isHead) {
if (_data.name && _data.name.length > 0) {
saveFolderTree(_data).then(res => {
if (res.msg === "ok") {
this.$message({
message: "新增成功",
type: "success"
});
this.$set(_data, "isHead", false);
this.isAdd = false;
this.getTreeselect();
} else {
this.$message({
message: "新增失败",
type: "error"
});
}
});
} else {
this.isAdd = false;
this.$message.error("名称不得为空!");
this.getTreeselect();
}
}
},
handleAdd(_node, _data) {
// 修改节点
// 退出编辑状态
if (_data.isAdd) {
if (_data.name && _data.name.length > 0) {
saveFolderTree(_data).then(res => {
if (res.msg === "ok") {
this.$message({
message: "新增成功",
type: "success"
});
this.isAdd = false;
this.getTreeselect();
} else {
this.$message({
message: "新增失败",
type: "error"
});
}
});
} else {
this.$message.error("名称不得为空!");
this.isAdd = false;
this.getTreeselect();
// return;
}
this.$set(_data, "isAdd", false);
}
},
handleAddTop() {
if (!this.isAdd) {
// 添加顶部节点
this.isAdd = true;
let obj = JSON.parse(JSON.stringify(this.initParamHead)); // copy参数
if(!(this.deptOptions && this.deptOptions.length>0)){
this.deptOptions = [];
}
this.deptOptions.push(obj);
this.$nextTick(() => {
if (this.$refs["slotTreeInputHead"]) {
this.$refs["slotTreeInputHead"].$refs.input.focus();
}
});
} else {
this.$message.error("请新增完毕后再次点击!");
return false;
}
},
removeTree(_node, _data) {
if (this.isAdd) {
this.$message.error("请完成上次操作后再次点击!");
return;
}
// 删除节点
// 判断是否存在子节点
if (_data.children && _data.children.length !== 0) {
this.$message.error("此节点有子级,不可删除!");
return false;
} else {
// 删除操作
let DeletOprate = () => {
this.$nextTick(() => {
if (this.$refs.tree) {
this.$refs.tree.remove(_data);
this.deleteData(_data);
// this.$message.success("删除成功!")
}
});
};
// 二次确认
let ConfirmFun = () => {
this.$confirm("是否删除此节点?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
DeletOprate();
})
.catch(() => {});
};
// 判断是否新增: 新增节点直接删除,已存在的节点要二次确认
_data[this.id] < this.NODE_ID_START ? DeletOprate() : ConfirmFun();
}
},
handleDragStart(node, ev) {
},
handleDragEnter(draggingNode, dropNode, ev) {
},
handleDragLeave(draggingNode, dropNode, ev) {
},
handleDragOver(draggingNode, dropNode, ev) {
},
handleDragEnd(draggingNode, dropNode, dropType, ev) {
},
handleDrop(draggingNode, dropNode, dropType, ev) {
var data = dropType != "inner" ? dropNode.parent.data : dropNode.data;
let updateData = draggingNode.data;
updateData.parentId = dropType != "inner" ? data.parentId : data.id;
updateData.parentIds =
dropType != "inner" ? data.parentIds : data.parentIds + "," + data.id;
if (!updateData.id) {
return;
}
//接口方法
update(updateData).then(res => {
if (res.msg === "ok") {
this.$message({
message: "拖拽成功",
type: "success"
});
this.getTreeselect();
} else {
this.$message({
message: "拖拽失败",
type: "error"
});
}
});
},