el-tree选中数据重组成树
vue+element-ui 实现el-tree选择重新生成一个已选中的值组成新的数据树,效果如下
<template>
<div class="flex">
<el-tree class="tree-row" :data="list" ref="tree" :props="{children: 'children', label: 'itemCategoryName'}" show-checkbox node-key="id" default-expand-all @check-change="getChecked">
</el-tree>
<el-tree class="tree-row" :data="selectedTreeData" :props="{children: 'children', label: 'itemCategoryName'}" node-key="id" default-expand-all :expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)">
Delete
</el-button>
</span>
</span>
</el-tree>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{
"id": "4100000000000071",
"itemCategoryCode": "001",
"itemCategoryName": "白酒类",
children: [{
"id": "41000020000000071",
"itemCategoryCode": "0012",
"itemCategoryName": "白酒类2",
children: [{
"id": "41000040000000071",
"itemCategoryCode": "0014",
"itemCategoryName": "白酒类4",
},
{
"id": "41000050000000071",
"itemCategoryCode": "0015",
"itemCategoryName": "白酒类5",
},
{
"id": "41000060000000071",
"itemCategoryCode": "0016",
"itemCategoryName": "白酒类6",
}]
},
{
"id": "41000030000000071",
"itemCategoryCode": "0013",
"itemCategoryName": "白酒类3",
}]
},
],
// selectedIds: ['41000040000000071', "41000060000000071"],
selectedTreeData:[]
}
},
created() {
},
methods: {
getChecked() {
this.selectedIds = this.$refs.tree.getCheckedKeys(true);
this.extractSubtrees();
},
extractSubtrees() {
const subtrees = [];
for (const id of this.selectedIds) {
const subtree = this.extractSubtree(this.list, id);
if (subtree) {
subtrees.push(subtree);
}
}
this.selectedTreeData = this.mergeSubtrees(subtrees);
},
extractSubtree(treeData, targetId) {
for (const node of treeData) {
if (node.id === targetId) {
// return this.cloneAndFilterChildren(node); 可以用这个也可以用下边的方式
return { ...node };
}
if (node.children) {
const subtree = this.extractSubtree(node.children, targetId);
if (subtree) {
// return this.cloneAndFilterChildren({ ...node, children: [subtree] });可以用这个也可以用下边的方式
return { ...node, children: [subtree] };
}
}
}
return null;
},
cloneAndFilterChildren(node) {
if (!node.children || node.children.length === 0) {
return { ...node, children: [] };
}
const filteredChildren = node.children
.map(child => this.cloneAndFilterChildren(child))
.filter(child => this.selectedIds.includes(child.id) || child.children.length > 0);
return { ...node, children: filteredChildren };
},
mergeSubtrees(subtrees) {
this.mergedTree = [];
const idMap = {};
for (const subtree of subtrees) {
this.addSubtreeToMergedTree(this.mergedTree, subtree, idMap);
}
return this.mergedTree;
},
addSubtreeToMergedTree(mergedTree, subtree, idMap) {
if (!subtree) return;
const node = { ...subtree, children: [] };
if (!idMap[node.id]) {
idMap[node.id] = node;
mergedTree.push(node);
} else {
// Object.assign(idMap[node.id], node);
}
if (subtree.children) {
for (const child of subtree.children) {
this.addSubtreeToMergedTree(mergedTree[mergedTree.length-1].children, child, idMap);
}
}
},
remove(node, data) {
let keys = [];
this.getRemovedIds(data,keys);
keys.map(item => {
this.selectedIds.splice(this.selectedIds.indexOf(item), 1);
})
this.$refs.tree.setCheckedKeys(this.selectedIds);
},
getRemovedIds(data,keys) {
if (data.children && data.children.length > 0) {
data.children.map(item => {
this.getRemovedIds(item,keys);
})
} else {
keys.push(data.id);
}
},
}
}
</script>
<style lang="less" scoped>
.flex {
display: flex;
justify-content: space-evenly;
}
.tree-row{
min-width: 200px;
}
.custom-tree-node{
display: flex;
flex:1;
justify-content: space-around;
}
</style>