前言
今天实现一个这样的 Web 前端需求,给定一个嵌套结构的 json 数据,计算每个非叶子节点中,其后代节点的个数,以及其后代节点中ID为一万倍数的个数,在此简单记录一下。
一、示例代码
(1)/src/views/Example/computeNodesNumber/index.vue
<template>
<div style="padding: 100px; background-color: #eee">
<el-tree
:data="treeData"
:props="defaultProps"
:show-checkbox="true"
:default-expand-all="true"
:highlight-current="true"
:expand-on-click-node="false"
:indent="22"
>
<template #default="{ node, data }">
<span v-if="!node.isLeaf" style="display: flex; align-items: center;">
<el-icon v-if="node.expanded" style="margin: 0 6px 0 0px;" size="16"><FolderOpened /></el-icon>
<el-icon v-else style="margin: 0 6px 0 0px;" size="16"><Folder /></el-icon>
<small @click="handleNodeClick(node, data)">
<i style="color: blue">{{ data.id }}</i>
{{ node.label }}
</small>
<b style="margin-left: 5px; padding: 0 3px; background-color: #eee; border: 1px solid #aaa;border-radius: 4px; color: #888; font-size: 13px;">
子节点个数:<i style="color: red">{{ handleComputeNodesNumber(data) }}</i>
</b>
<b style="margin-left: 5px; padding: 0 3px; background-color: #eee; border: 1px solid #aaa;border-radius: 4px; color: #888; font-size: 13px;">
子节点中ID为10000倍数的个数:<i style="color: deeppink">{{ handleComputeNodesNumber_10000(data) }}</i>
</b>
</span>
<span v-else style="display: flex; align-items: center;">
<el-icon style="margin: 0 6px 0 0px;" size="16"><Document /></el-icon>
<small @click="handleNodeClick(node, data)">
<i style="color: cornflowerblue">{{ data.id }}</i>
{{ node.label }}
</small>
</span>
</template>
</el-tree>
</div>
</template>
<script>
import * as treeObj from './tree.json'
const treeData = treeObj.default
const defaultProps = {
children: 'children',
label: 'label',
}
export default {
data() {
return {
treeData: treeData,
defaultProps: defaultProps,
}
},
mounted() {
console.log(treeObj)
},
methods: {
/**
* 计算子节点个数句柄方法
*/
handleComputeNodesNumber(data) {
// 当前节点的数据
const nodeData = data
console.log(nodeData)
// 计算这个节点的叶子节点总数
let sum = 0
sum = this.computeNodesNumberAssist(0, nodeData.children)
console.log('sum =>', sum)
return sum
},
/**
* 计算子节点个数辅助方法
*/
computeNodesNumberAssist(sum, tree) {
for (let i in tree) {
sum++
if (tree[i].children) {
sum += this.computeNodesNumberAssist(0, tree[i].children)
}
}
return sum
},
/**
* 计算子节点中ID为10000倍数的个数句柄方法
*/
handleComputeNodesNumber_10000(data) {
// 当前节点的数据
const nodeData = data
console.log(nodeData)
// 计算这个节点的符合的叶子节点总数
let sum = 0
sum = this.computeNodesNumberAssist_10000(0, nodeData.children)
console.log('sum =>', sum)
return sum
},
/**
* 计算子节点中ID为10000倍数的个数辅助方法
*/
computeNodesNumberAssist_10000(sum, tree) {
for (let i in tree) {
if ((tree[i].id % 10000) == 0) {
sum++
}
if (tree[i].children) {
sum += this.computeNodesNumberAssist_10000(0, tree[i].children)
}
}
return sum
},
/**
* 树节点点击事件句柄方法
*/
handleNodeClick(node, data) {
console.log('handleNodeClick =>', node, data)
}
},
};
</script>
(2)/src/views/Example/computeNodesNumber/tree.json
[
{
"id": 1,
"label": "香烟 WiFi 啤酒"
},
{
"id": 2,
"label": "后端开发技术",
"children": [
{
"id": 3,
"label": "Java后端",
"children": [
{
"id": 5,
"label": "Spring MVC",
"children": [
{
"id": 15,
"label": "AOP 面向切面编程",
"children": [
{
"id": 750000,
"label": "切面(aspect)"
},
{
"id": 760000,
"label": "横切关注点"
},
{
"id": 770000,
"label": "连接点(joinpoint)"
},
{
"id": 780000,
"label": "切入点(pointcut)"
},
{
"id": 790000,
"label": "通知(advice)"
},
{
"id": 800000,
"label": "目标对象"
},
{
"id": 810000,
"label": "织入(weave)"
}
]
},
{
"id": 16,
"label": "IOC 控制反转",
"children": [
{
"id": 410000,
"label": "依赖查找"
},
{
"id": 420000,
"label": "依赖注入"
}
]
}
]
},
{
"id": 6,
"label": "Hibernate",
"children": [
{
"id": 110000,
"label": "HSQL Database Engine"
},
{
"id": 120000,
"label": "DB2/NT"
},
{
"id": 130000,
"label": "MySQL"
},
{
"id": 140000,
"label": "PostgreSQL"
},
{
"id": 150000,
"label": "FrontBase"
},
{
"id": 160000,
"label": "Oracle"
},
{
"id": 170000,
"label": "Microsoft SQL Server Database"
}
]
}
]
},
{
"id": 4,
"label": "Web 前端",
"children": [
{
"id": 13,
"label": "Vue",
"children": [
{
"id": 260000,
"label": "响应式"
},
{
"id": 290000,
"label": "条件渲染"
},
{
"id": 420000,
"label": "列表渲染"
},
{
"id": 500000,
"label": "事件处理"
},
{
"id": 510000,
"label": "生命周期"
},
{
"id": 620000,
"label": "侦听器"
},
{
"id": 650000,
"label": "插槽"
},
{
"id": 720000,
"label": "依赖注入"
},
{
"id": 730000,
"label": "异步组件"
}
]
},
{
"id": 14,
"label": "React",
"children": [
{
"id": 310000,
"label": "虚拟DOM"
},
{
"id": 320000,
"label": "Diff算法"
}
]
},
{
"id": 48,
"label": "Angular"
},
{
"id": 58,
"label": "JQuery"
},
{
"id": 900000,
"label": "HTML+CSS+JS"
}
]
}
]
}
]
二、运行效果