需求 树形结构展示数据 且数据可被选中 在数据后显示选中数量
测试数据
[
{
"title": "测试",
"key": 6,
"children": [
{
"title": "测试测试",
"key": "6-1",
"children": [
{
"title": "Band-测试",
"key": "6-1-60",
"scopedSlots": {
"title": "title"
}
},
{
"title": "Band1-Band1",
"key": "6-1-61",
"scopedSlots": {
"title": "title"
}
}
],
"scopedSlots": {
"title": "title"
},
"lengthNum": 2,
"allianceType": "children"
},
{
"title": "测试测试1",
"key": "6-2",
"children": [
{
"title": "null-null",
"key": "6-2-62",
"scopedSlots": {
"title": "title"
}
},
{
"title": "Band-Band",
"key": "6-2-63",
"scopedSlots": {
"title": "title"
}
}
],
"scopedSlots": {
"title": "title"
},
"lengthNum": 2,
"allianceType": "children"
}
],
"allianceType": "HEAD",
"scopedSlots": {
"title": "title"
}
},
{
"title": "测试",
"key": 7,
"children": [
{
"title": "测试3",
"key": "7-4",
"children": [ ],
"scopedSlots": {
"title": "title"
},
"lengthNum": 0,
"allianceType": "children"
},
{
"title": "测试3",
"key": "7-3",
"children": [
{
"title": "Band-Band",
"key": "7-3-64",
"scopedSlots": {
"title": "title"
}
},
{
"title": "Band-Band",
"key": "7-3-65",
"scopedSlots": {
"title": "title"
}
}
],
"scopedSlots": {
"title": "title"
},
"lengthNum": 2,
"allianceType": "children"
}
],
"allianceType": "BRANCH",
"scopedSlots": {
"title": "title"
}
}
]
vue代码
<div>
<a-input-search
style="margin-bottom: 8px"
placeholder="搜索用户组"
@change="onChange"
/>
<a-tree
v-model="checkedKeys"
:expanded-keys="expandedKeys"
:auto-expand-parent="autoExpandParent"
checkable
:tree-data="gData"
@expand="onExpand"
>
<template slot="title" slot-scope="title">
<span v-if="title.title.indexOf(searchValue) > -1">
{{ title.title.substr(0, title.title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}span>
{{
title.title.substr(
title.title.indexOf(searchValue) + searchValue.length
)
}}
<span v-if="title.allianceType">
({{ statisticalSelection(title) }}/{{
title.allianceType !== "children"
? title.children
.map((item) => item.lengthNum)
.reduce((a, b) => a + b)
: title.lengthNum
? title.lengthNum
: 0
}})span
>
span>
<span v-else
>{{ title.title }}
<span v-if="title.allianceType">
(({{ statisticalSelection(title) }}/{{
title.allianceType
? title.children
.map((item) => item.lengthNum)
.reduce((a, b) => a + b)
: title.lengthNum || 0
}})span
>
span>
template>
a-tree>
div>
js代码
//data里放
gData: [],
checkedKeys:[],
expandedKeys: [],
autoExpandParent: true,
//methods里放
onExpand(expandedKeys) {
this.expandedKeys = expandedKeys;
this.autoExpandParent = false;
},
statisticalSelection(title) {
//遍历选中数组
let num = 0;
this.checkedKeys
.map(item => {
//是当前渲染时进入
if (item == title.key) {
//是爷进
if (title?.allianceType !== "children") {
return title.children
.map(item => item.lengthNum)
.reduce((a, b) => a + b);
} else {
//否则是儿
console.log("儿子", item, title.key);
return title.lengthNum;
}
} else {
//选中子元素
//爷进
if (
!this.checkedKeys.includes(title.key) &&
title.allianceType !== "children"
) {
console.log("爷爷判断儿子是否被选中");
return title.children
.map(cont => {
if (item == cont.key) {
console.log("选中了儿子");
return cont.lengthNum;
} else if (
!this.checkedKeys.includes(cont.key) &&
cont.children.map(item => item.key).includes(item)
) {
console.log("孙子选中了");
return 1;
}
return 0;
})
.reduce((a, b) => {
return a + b;
});
} else if (
!this.checkedKeys.includes(title.key) &&
title.allianceType == "children"
) {
if (title.children.map(item => item.key).includes(item)) {
return 1;
}
}
}
})
.filter(a => a)
.map(item => {
num += item;
});
return num;
},
//放vue外 js内
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};