之前写过这个,有地址
https://blog.csdn.net/weixin_44191425/article/details/119740500?spm=1001.2014.3001.5501
现在只是为了更优化丰富一下,然后修复了一些bug
结合之前的和现在的看,会更明白。
基于之前封装的组件,优化了一些bug,比如说编辑和新增的时候做了其他操作,新增的输入框和编辑框要恢复到之前的状态。
<template>
<div>
<a-tree
v-if="treeData.length > 0"
:tree-data="treeData"
block-node
default-expand-all
style="margin-top:65px;"
>
<icon slot="switcherIcon" name="down"></icon>
<template slot="custom" slot-scope="item">
<!-- 如果是新增-->
<span v-if="item.isNewItem">
<input
type="text"
class="editInput"
:maxlength="30"
v-model="item.name"
placeholder="请输入部门名称"
/>
<span
class="tree-save_icon edit-require_icon"
@click="submitAddFun(item)"
>
<a-icon type="check-circle" />
</span>
<span
class="tree-cancle_icon edit-require_icon"
@click="cancelAddFun(item)"
>
<a-icon type="close-circle" />
</span>
</span>
<!-- 不是新增 -->
<div v-else>
<!-- 编辑时展示输入框 -->
<div v-if="item.isEdit">
<input
type="text"
v-model="item.title"
:maxlength="30"
class="editInput"
/>
<span
class="tree-save_icon edit-require_icon"
@click="submitEdit(item)"
>
<a-icon type="check-circle" />
</span>
<span
class="tree-cancle_icon edit-require_icon"
@click="cancelEdit(item.id, false)"
>
<a-icon type="close-circle" />
</span>
</div>
<!-- 否则展示原来的节点信息 -->
<div v-else>
<!-- <a-popover placement="topLeft"> -->
<!-- <template slot="content">
<p>{{ item.title }}</p>
</template> -->
<span class="node-title" @click="selectNode(item)" >{{
item.title
}}</span>
<!-- </a-popover> -->
<!-- 删除按钮 -->
<a-popconfirm
class="delete-box"
placement="topRight"
ok-text="确定"
cancel-text="取消"
overlayClassName="staff-delete-pop"
@confirm="deleteNode(item)"
v-show="item.isShowDelete"
>
<template slot="title">
删除{{
item.title
}}后,该部门下的所有员工将被删除,且已存在的演练数据也将去除,确定删除
?
</template>
<a-tooltip placement="top">
<template slot="title">
<span>删除</span>
</template>
<span class="icon-wrap" @click="cancelBubble($event)" style="margin-left:8px">
<icon name="delete-opt" />
</span>
</a-tooltip>
</a-popconfirm>
<!-- 编辑按钮 -->
<template v-if="item.isShowEdit">
<a-tooltip placement="top">
<template slot="title">
<span>编辑</span>
</template>
<span class="icon-wrap" @click="editNode(item.id)">
<icon name="edit-opt" />
</span>
</a-tooltip>
</template>
<!-- 新增按钮 -->
<a-tooltip v-if="item.isShowAdd" placement="top">
<template slot="title">
<span>新增</span>
</template>
<span class="icon-wrap" @click="addNewNode(item)">
<icon name="plus" />
</span>
</a-tooltip>
</div>
</div>
</template>
</a-tree>
</div>
</template>
<script>
import {
addOrganization,
deleteOrganization,
editOrganization,
} from "@/api/staff.js";
export default {
props: {
treeData: {
type: Array,
default: () => [],
},
},
data() {
return {
tempTable: [],
};
},
mounted() {
this.visible = false;
},
methods: {
// 选择单条查询
selectNode(node) {
this.deleteEditInput()
this.deleteAddInput()
this.$emit("getParams", node);
},
// 删除取消气泡
cancelBubble(e) {
e.stopPropagation();
},
// 新增节点
addNewNode(node) {
this.deleteEditInput()
const newNode = {
addNode: true,
id: Math.ceil(Math.random() * 10000),
key: Math.ceil(Math.random() * 10000),
isEdit: false,
name: "",
isNewItem: true,
title: "",
status: node.status,
depth: node.depth + 1,
parent_id: node.id,
parent_name: node.title,
scopedSlots: { title: "custom" },
};
this.$nextTick(() => {
for (let i = 0; i < this.treeData.length; i++) {
if (this.treeData[i].id === node.id) {
this.deleteAddInput();
this.treeData[i].children.unshift(newNode);
}
}
});
},
// 删除新增的input框
deleteAddInput() {
for (let i = 0; i < this.treeData.length; i++) {
// 父级
if (this.treeData[i].addNode) {
this.treeData.splice(i, 1);
// 子集
} else {
this.deleteChildren(this.treeData[i].children);
}
}
},
// 删除子集
deleteChildren(data) {
if (!data.length) return;
for (let j = 0; j < data.length; j++) {
// 删除已有的输入框
if (data[j].addNode) {
data.splice(j, 1);
}
}
},
// 提交新增
submitAddFun(node) {
if (!node.name) {
this.$message.error("部门名称不能为空!");
return;
}
let params = {
name: node.name,
parentId: node.parent_id,
};
addOrganization(params).then((res) => {
if (res.errorCode === "00000") {
this.deleteAddInput();
this.$message.success("部门新增成功");
this.$emit('refrshAdd');
}
});
},
// 取消新增
cancelAddFun() {
this.deleteAddInput();
},
// 删除节点内容
deleteNode(item) {
deleteOrganization({ id: item.id }).then((res) => {
if (res.errorCode === "00000") {
this.$message.success("部门删除成功");
// 接口请求成功之后做本地删除
this.treeData[0].children = this.treeData[0].children.filter(ele => ele.id != item.id)
// 删除一条补一条最新的
this.$emit("deleteAfterAdd");
// 刷新列表
this.$emit("resetList");
} else {
this.$message.error(res.message);
}
});
},
// 编辑
editNode(id) {
this.deleteAddInput()
const copyData = this.treeData;
copyData.forEach((ele) => {
// 父级编辑
if (ele.id == id) {
this.$set(ele, "isEdit", true);
} else {
ele.children.forEach((ite) => {
if (ite.id == id) {
this.$set(ite, "isEdit", true);
} else {
this.$set(ite, "isEdit", false);
}
});
}
});
},
// 撤销编辑框
deleteEditInput() {
this.treeData.forEach( item => {
item.children.forEach( ite => {
this.$set(ite, "isEdit", false);
})
})
},
// 取消编辑
cancelEdit(id, isEdit) {
const copyData = this.treeData[0].children;
copyData.forEach((ele) => {
// 父级编辑
if (ele.id == id) {
this.$set(ele, "isEdit", isEdit);
return;
}
});
},
// 提交编辑
submitEdit(data) {
if (!data.title) {
this.$message.error("部门名称不能为空!");
return;
}
let params = {
id: data.id,
name: data.title,
parentId: data.parent_id,
};
editOrganization(params).then((res) => {
if (res.errorCode === "00000") {
this.$message.success("部门修改成功");
// 接口请求成功之后做本地修改
const copyData = this.treeData[0].children;
copyData.forEach((ele) => {
// 父级编辑
if (ele.id == data.id) {
this.$set(ele, "isEdit", false);
this.$set(ele, "title", data.title);
return;
}
});
// 修改部门成功之后刷新员工列表
this.$parent.pagination({page:1,page_size:10})
} else {
this.$message.error(res.message);
}
});
},
},
watch: {},
};
</script>
<style lang="less" scoped>
.icon-wrap {
float: right;
color: #999999;
}
/deep/ .ant-tree>li>.ant-tree-node-content-wrapper{
background: #FAFAFA;
}
/deep/.ant-tree>li>span.ant-tree-switcher, .ant-tree li span.ant-tree-iconEle{
line-height: 32px !important;
}
/deep/ .ant-tree-child-tree {
padding-left: 23px;
margin-top: 10px;
li {
list-style: none;
.ant-tree-node-content-wrapper {
height: 32px !important;
.icon-wrap{
visibility: hidden;
}
&:hover {
background: #f6f9ff;
.icon-wrap{
visibility: inherit;
}
}
}
.node-title{
padding-left:30px ;
}
}
.ant-tree-treenode-switcher-open {
vertical-align: middle;
line-height: 35px;
height: 40px;
.ant-tree-node-content-wrapper {
margin-top: 3px;
width: 100% !important;
line-height: 32px;
height: 32px;
&:hover {
background: #f6f9ff;
}
}
}
.ant-tree-treenode-switcher-close{
position: relative;
&::before{
position: absolute;
top: 18px;
left: 18px;
vertical-align: middle;
width: 4px;
height: 4px;
border-radius: 50%;
background: #333333;
content: '';
}
&:first-child::before{
top: 22px;
}
}
.ant-tree-switcher-noop {
width: 0;
}
}
/deep/.ant-tree-node-content-wrapper.ant-tree-node-content-wrapper-normal {
width: 100% !important;
line-height: 32px;
height: 32px;
}
/deep/.ant-tree-node-selected {
height: 32px;
background: #f6f9ff;
}
/deep/ .edit-require_icon {
margin-left: 5px;
}
.editInput {
width: 70%;
height: 30px;
margin-left: 25px;
line-height: 30px;
outline: none;
border: 1px solid @line-gray;
background: transparent;
font-size: 12px;
}
/deep/ .ant-tree-title div {
line-height: 32px;
height: 32px;
&:hover {
background: #f6f9ff;
}
}
.node-title{
width: 70%;
padding-left: 10px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: inline-block;
}
</style>
部门树增加滑动加载、搜索查询

// 左侧关键词查询
handelLeftSearch(e) {
this.leftTreeSearch.keyword = e.target.value ? e.target.value : null;
this.leftTreeSearch.page = 1;
this.getOrganizationList(this.treeData);
},
// 左侧部门树滑动加载
scroll() {
this.$nextTick(() => {
const el = this.$refs.leftTreeList;
const offsetHeight = el.offsetHeight;
const scrollTop = el.scrollTop;
const scrollHeight = el.scrollHeight;
if (offsetHeight + scrollTop - scrollHeight >= 0) {
// 查询聚合数据
this.getOrganizationList(this.treeData);
}
});
},
getOrganizationList(dataArr) {
if (this.treeLoading) {
return;
}
this.treeLoading = true;
organizationList(this.leftTreeSearch).then((res) => {
if (res.errorCode == "00000") {
let handelData = res.data.records;
if (handelData.length == 0) {
this.treeLoading = false;
return;
}
// 如果是搜索渲染数据
if (this.leftTreeSearch.page == 1) {
dataArr[0].children = [];
}
handelData.forEach((item) => {
item.parentId = dataArr[0].id;
item.key = item.id;
item.title = item.name;
item.depth = 2;
item.isEdit = false;
item.isNewItem = false;
item.isDelete = false;
item.isShowDelete = true;
item.isShowEdit = true;
item.isShowAdd = false;
item.scopedSlots = { title: "custom" };
dataArr[0].children.push(item);
});
this.leftTreeSearch.page += 1;
this.treeLoading = false;
}
});
this.treeData = dataArr;
},
版权声明:本文为weixin_44191425原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。