目的
实现el-tree两个树,将左边的树数据添加到右边的树中,当右边存在左边el-tree数据,这个子节点禁用,当右边el-tree删除掉那个子节点,左边el-tree那个节点可以选择
展示
代码
<template>
<div class="container">
<div style="padding: 20px 0">
<el-form :inline="true" :model="formInline">
<el-col :span="22">
<el-form-item label="品牌名称">
<el-select
v-model="formInline.brandCode"
style="width: 300px"
clearable
filterable
default-first-option
placeholder="请选择"
>
<el-option
v-for="(item, index) in brandNameArr"
:key="item.brandCode + index"
:label="item.brandName"
:value="item.brandCode"
/>
</el-select>
</el-form-item>
</el-col>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
</div>
<div>
<div class="tree-drag">
<el-col :span="10">
<div class="tree">
<h4>AI智能标签</h4>
<el-tree
ref="aiTree"
:data="treeData2"
default-expand-all
show-checkbox
node-key="id"
:check-strictly="true"
:disabled="checkDisabled"
@check="checkSelect"
:props="defaultProps"
>
</el-tree>
</div>
</el-col>
<el-col :span="4">
<div class="btn">
<el-button
type="primary"
:disabled="chooseList.length > 0 ? false : true"
@click="moveBtn"
>
添加映射到主标签</el-button
>
<!-- <el-button
type="primary"
:disabled="leftChooseTable.length > 0 ? false : true"
@click="rightChangeTable('right')"
>移动至AI标签<i class="el-icon-arrow-right el-icon--right" />
</el-button> -->
</div>
</el-col>
<el-col :span="10">
<div class="tree">
<h4>系统默认标签</h4>
<!-- <el-tree
ref="tree"
:data="treeData1"
default-expand-all
node-key="id"
>
</el-tree> -->
<el-tree
ref="tree"
:data="treeData1"
default-expand-all
node-key="id"
:props="defaultProps"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span v-if="data.isAi">
<span
style="margin: 0 10px; font-size: 14px; color: deepskyblue"
class="iconfont icon-ai"
>{{ data.label }}</span
>
<el-button
type="text"
size="mini"
style="color: red; font-size: 14px"
@click="() => remove(node, data)"
>
删除
</el-button>
</span>
<span v-else>{{ node.label }}</span>
</span>
</el-tree>
</div>
</el-col>
</div>
<el-dialog
title="请选择映射到主档标签"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose"
center
>
<div>
<el-tree
:data="treeData1"
show-checkbox
default-expand-all
@check-change="checkChange"
ref="Tree"
:check-strictly="true"
node-key="id"
:props="defaultProps"
></el-tree>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button type="primary" @click="addBtn">确 定</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import http from "@/utils/request";
export default {
data() {
return {
dialogVisible: false,
chooseList: [],
rightChooseInfo: [],
treeData1: [],
treeData2: [],
disabledNodes: [],
value: "",
idListArr: [],
formInline: {
brandCode: "",
},
defaultProps: {
children: "children",
label: "label",
},
};
},
computed: {
checkDisabled() {
return (node) => {
return this.disabledNodes.includes(node.id);
};
},
},
created() {
this.getAllBrand();
// console.log(this.setDisabled(data));
},
methods: {
// 查询
onSubmit() {
const data = [
{
id: 1,
label: "标签主档",
children: [
{
id: 2,
label: "投诉",
children: [
{ id: 21, label: "催单" },
{ id: 22, label: "提前关单" },
],
},
{
id: 3,
label: "错漏送",
children: [
{ id: 31, label: "漏配料" },
{ id: 32, label: "漏餐具" },
],
},
{
id: 4,
label: "服务态度",
children: [
{
id: 41,
label: "骑手服务态度",
},
{ id: 42, label: "门店服务态度" },
],
},
],
},
];
const data2 = [
{
id: 111,
label: "AI标签分类",
children: [
{
id: 211,
label: "骑手未送达",
},
{
id: 311,
label: "漏番茄酱",
isAll: true,
},
{
id: 411,
label: "漏料包",
},
],
},
];
this.treeData1 = this.addDisabledToParentNodes(data);
this.treeData2 = this.addDisabledToParentNodes(data2);
console.log(this.treeData2);
},
// 获取所有品牌
getAllBrand() {
},
// 关闭
closeDialog() {
this.dialogVisible = false;
},
// 提交
addBtn() {
if (this.value) {
this.traverseTree(this.treeData1);
}
},
traverseTree(treeData) {
for (let i = 0; i < treeData.length; i++) {
let node = treeData[i];
console.log(node); // 打印当前节点
if (node.children && node.children.length > 0) {
this.traverseTree(node.children); // 递归遍历子节点
}
if (node.id == ~~this.value) {
if (!node.children) {
// 如果该节点没有children属性,则创建它
node.children = [];
}
node.children.push(...this.chooseList);
this.dialogVisible = false;
// 取消勾选
this.$refs.aiTree.setCheckedKeys([]);
}
this.treeData1 = JSON.parse(JSON.stringify(treeData));
this.$nextTick(() => {
this.chooseList = [];
this.value = "";
});
}
},
moveBtn() {
this.dialogVisible = true;
},
// 选中复选框触发
checkChange(currObj, isChecked) {
if (isChecked) {
// 选中之后我们就重新设置下选中的节点(只设置当前选中的节点,即单选)
this.$refs.Tree.setCheckedNodes([currObj]);
this.value = currObj.id;
console.log(111, this.value);
}
},
addDisabledToParentNodes(data) {
return data.map((node) => {
// 如果当前节点有子节点,则递归处理子节点
if (node.children && node.children.length > 0) {
node.children = this.addDisabledToParentNodes(node.children);
// 如果当前节点是父节点,则添加disabled属性
node.disabled = true;
}
if (node.isAll) {
node.disabled = true;
}
return node;
});
},
checkSelect(select, val) {
console.log(select, val);
this.chooseList = val.checkedNodes.map((item) => {
return { ...item, isAi: true };
});
this.idListArr = val.checkedKeys;
console.log(1111111111, this.chooseList);
},
handleClose() {
this.dialogVisible = false;
},
// 删除AI智能标签
remove(node, data) {
console.log("删除", node, data);
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex((d) => d.id === data.id);
this.$confirm("此操作将永久删除该标签映射, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
children.splice(index, 1);
this.$message({
type: "success",
message: "删除成功!",
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
},
};
</script>
<style lang="scss" scoped>
@font-face {
font-family: "iconfont"; /* Project id 4368207 */
/* Color fonts */
src: url("//at.alicdn.com/t/c/font_4368207_u2wqj9e0d6h.woff2?t=1702287717799")
format("woff2"),
url("//at.alicdn.com/t/c/font_4368207_u2wqj9e0d6h.woff?t=1702287717799")
format("woff"),
url("//at.alicdn.com/t/c/font_4368207_u2wqj9e0d6h.ttf?t=1702287717799")
format("truetype");
}
.iconfont {
font-family: "iconfont" !important;
font-size: 14px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-ai:before {
content: "\e68a";
margin-right: 5px;
}
.container {
display: flex;
flex-direction: column;
padding: 20px;
}
.tree-drag {
display: flex;
justify-content: space-between;
}
.tree {
display: flex;
flex-direction: column;
align-items: center;
overflow: auto;
height: 500px;
font-size: 14px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border: 1px solid #ccc;
}
.btn {
height: 500px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.el-button {
width: 150px;
margin: 10px 0;
}
}
/* 隐藏掉el-tree中有disabled属性的框框 */
.el-checkbox__input.is-disabled {
display: none;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
提示
移动的数据让后端添加上一个标识,删除的数据同样加上标识