公司树
一、基础准备:
1.1 数据库建表要有层级关系:
如上图所示,通过id
和pid
建立层级关系。其中pid
为父级公司的id
,而leaf
是为表明该公司是否存在子公司,当leaf
为1(true)
时表明在公司树结构中为叶子,因此下方不包含子公司。
数据中的层级结构如下:
二、懒加载:
2.1 代码实现:
<template>
<div>
<div>
<!--element的tree组件-->
<el-tree
:props="props"
:load="loadNode"
lazy>
</el-tree>
</div>
</div>
</template>
<script>
export default {
data() {
return {
props: {
label: 'name',
children: 'zones',
isLeaf: 'leaf'
},
// 这里模拟数据库
company: [
{id: '0', pid: '0', name:'腾讯', leaf: false},
{id: '1', pid: '0', name: '天美游戏公司', leaf: true},
{id: '2', pid: '0', name: '微信', leaf: false},
{id: '3', pid: '2', name:'微信公众号', leaf: false},
{id: '4', pid:'3', name:'微信小程序', leaf: true}
]
}
},
methods: {
// 树节点进行点击,懒加载
loadNode(node, resolve) {
if (node.level === 0) {
return resolve(this.getRootCompany());
}
// 通过延时操作,模仿接口访问时间
setTimeout(() => {
const data = this.getSubCompany(node.data.id);
resolve(data);
}, 500);
},
// 根据pid获取子公司(模拟接口调用反参)
getSubCompany(pid){
const subCompany = this.company.filter(item=>{
return item.pid === pid && item.pid !== item.id;
})
return subCompany;
},
// 获取根公司(模拟接口调用反参)
getRootCompany(){
const rootCompany = this.company.filter(item=>{
return item.pid === item.id;
})
return rootCompany;
}
},
}
</script>
2.2运行结果:
2.3 优点:
- 代码实现简单
- 不要需要将数据转换树型结构
- 当数据过多时(10万个公司),减少运算处理的压力
三、及时加载
3.1 前端代码实现:
<template>
<div>
<h2>前端实现</h2>
<div @click="transformTozTreeFormat">
<el-tree
:data="treeData"
:props="defaultProps"
@node-click="handleNodeClick">
</el-tree>
</div>
</div>
</template>
<script>
export default {
data() {
return {
treeData:[],
defaultProps: {
children: 'children',
label: 'name'
},
// 模仿接口反参数
company: [
{id: '0', pid: '0', name:'腾讯'},
{id: '1', pid: '0', name: '天美游戏公司'},
{id: '2', pid: '0', name: '微信'},
{id: '3', pid: '2', name:'微信公众号',},
{id: '4', pid:'3', name:'微信小程序'}
]
}
},
created(){
this.getTree();
},
methods: {
// 给你树结构赋值
getTree(){
this.treeData = this.transformTozTreeFormat(this.company);
},
// 将数据转换为树结构
transformTozTreeFormat(sNodes) {
let i, l
let r = []
let tmpMap = {}
for (i = 0, l = sNodes.length; i < l; i++) {
tmpMap[sNodes[i].id] = sNodes[i]
}
for (i = 0, l = sNodes.length; i < l; i++) {
let p = tmpMap[sNodes[i].pid]
if (p && sNodes[i].id !== sNodes[i].pid) {
let children = this.nodeChildren(p)
if (!children) {
children = this.nodeChildren(p, [])
}
children.push(sNodes[i])
} else {
r.push(sNodes[i])
}
}
return r
},
// 添加子几点
nodeChildren: function (node, newChildren) {
if (typeof newChildren !== 'undefined') {
node.children = newChildren
}
return node.children
}
},
}
</script>
3.2运行结果:
3.3java后端实现:
公司对象
public class OrgTree {
/** 公司id**/
private String id;
/** 父级id*/
private String pid;
/** 公司名称*/
private String name;
/** 子集*/
private List<OrgTree> children;
}
生成树结构
public List<OrgTree> getOrgTree() {
List<OrgTree> orgList = orgTreeMapper.getList();
for (OrgTree org : orgList) {
List<OrgTree> filterOut = orgList
.stream()
.filter(item -> item.getPid().equals(org.getId()))
.collect(Collectors.toList());
org.setChildren(filterOut);
}
ArrayList<OrgTree> orgTrees = new ArrayList<>();
orgTrees.add(orgList.get(0));
return orgTrees;
}
postman测试