<a-tree v-if="treeDataFlag" v-model:selectedKeys="selectedKeys" v-model:checkedKeys="checkedKeys"
:field-names="{ key: 'typeCode', title: 'typeDesc' }" checkable class="template-tree" defaultExpandAll
:tree-data="treeData">
<template #title="{ typeDesc, typeDescEn }">
<span>{{ typeDesc }}</span>
<span v-if="typeDescEn"> ({{ typeDescEn }})</span>
</template>
</a-tree>
treeData: [],
expandedKeys: [], // 展开树
checkedKeys: [], // 默认树
selectedKeys: [], // 选中树
treeDataFlag: false,
this.treeData = this.addClassToLeafNodes(res.totalLevel);
addClassToLeafNodes(treeData, processedItems = [], isFirstLevel = true) {
_.forEach(treeData, item => {
if (processedItems.includes(item)) return;
processedItems.push(item);
if (isFirstLevel) {
item.class = (item.class || '') + ' first-parent-node';
}
if (_.isEmpty(item.children)) {
item.class = (item.class || '') + ' leaf-node';
} else {
item.class = (item.class || '') + ' parent-node';
this.addClassToLeafNodes(item.children, processedItems, false);
}
});
return treeData;
},
<style lang="scss">
.template-tree {
.ant-tree-list-holder-inner {
display: inline-block !important;
}
.first-parent-node {
background: #e6f4ff !important;
margin-top: 8px;
}
.leaf-node {
display: inline-flex !important;
}
}
</style>
回显部分:
//res.supplierProductTypeCategoryVos被选中的值
this.treeData = this.formatTreeData(this.treeData, res.supplierProductTypeCategoryVos);
formatTreeData(data, filterData) {
// 使用Lodash的深度拷贝
const treeListData = _.cloneDeep(data);
function filterRecursive(tree) {
return _.filter(tree, item => {
if (_.size(item.children)) {
item.children = filterRecursive(item.children);
const hasChildrenAfterFilter = _.size(item.children) > 0;
// 如果子节点都被过滤掉,且当前节点也不匹配filterData,则不保留该节点
if (!hasChildrenAfterFilter && !_.some(filterData, fd => fd.productTypeCategoryCode === item.typeCode)) {
return false;
}
} else {
// 如果当前节点无子节点,仅当它匹配filterData时才保留
return _.some(filterData, fd => fd.productTypeCategoryCode === item.typeCode);
}
// 如果以上条件满足其一,则保留当前节点
return true;
});
}
return filterRecursive(treeListData);
},
比较树
<a-tree v-if="originTreeData.length" :field-names="{ key: 'typeCode', title: 'typeDesc' }" class="template-tree template-compare-tree" defaultExpandAll
:tree-data="originTreeData">
<template #title="{ typeDesc, typeDescEn }">
<span>{{ typeDesc }}</span>
<span v-if="typeDescEn"> ({{ typeDescEn }})</span>
</template>
</a-tree>
this.originTreeData = this.formatTreeData2(this.originTreeData, res.supplierProductTypeCategoryVos);
formatTreeData2(data, filterData) {
const treeListData = _.cloneDeep(data);
function filterAndMarkLeafNodes(tree) {
return _.map(tree, item => {
if (_.size(item.children)) {
item.children = filterAndMarkLeafNodes(item.children);
const hasChildrenAfterFilter = _.size(item.children) > 0;
// 如果子节点都被过滤掉,且当前节点也不匹配filterData,不删除节点,但不添加class
if (!hasChildrenAfterFilter && !_.some(filterData, fd => fd.productTypeCategoryCode === item.typeCode)) {
return item;
}
} else {
// 如果当前节点无子节点,仅当它匹配filterData时保留并添加class
if (_.some(filterData, fd => fd.productTypeCategoryCode === item.typeCode)) {
item['class'] = item['class'] ? `${item['class']} select-leaf-node` : 'select-leaf-node';
}
}
// 返回当前节点,无论是否添加了class
return item;
});
}
return filterAndMarkLeafNodes(treeListData);
},