搜索elementui文档 找到一个朴实无华的demo 如下
之后查看其源码如下
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
<script>
export default {
data() {
return {
data: [{
label: '一级 1',
children: [{
label: '二级 1-1',
children: [{
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
children: [{
label: '二级 2-1',
children: [{
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
children: [{
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
children: [{
label: '二级 3-1',
children: [{
label: '三级 3-1-1'
}]
}, {
label: '二级 3-2',
children: [{
label: '三级 3-2-1'
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
}
}
};
</script>
由此可见 elementui的tree组件所需要的数据结构 为 label 显示名 和 hildren 子节点 两个属性
于是我们去后台新建vo来构造该组件的返回数据 如下
@Data
public class BusConfDeviceTypeVO {
//节点id
private String id ;
//节点名称
private String name;
//节点的子节点
private List<BusConfDeviceTypeVO> children;
}
我所创建的数据库非常简单 我默认-1 为数据的顶级节点的父节点
CREATE TABLE `bus_conf_device_type` (
`id` varchar(50) NOT NULL,
`status` int(11) DEFAULT NULL COMMENT '数据有效 0 已删除 1',
`pid` varchar(50) DEFAULT NULL COMMENT '父节点',
`device_type` varchar(50) DEFAULT NULL COMMENT '设备类型',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
之后开始进行递归操作来构建数据
@Override
public List<BusConfDeviceTypeVO> getTreeData() {
List<BusConfDeviceTypeVO> deviceTypeTree = new ArrayList<>();
//首先获取到所有顶级节点
BusConfDeviceType param = new BusConfDeviceType();
//查询全部
List<BusConfDeviceType> selectAll = this.deviceTypeMapper.select(param);
param.setPid("-1");
//查询顶级父节点
List<BusConfDeviceType> select = this.deviceTypeMapper.select(param);
//结果判断
if (select.size() > 0 && select != null){
select.forEach(data -> {
BusConfDeviceTypeVO deviceTypeVO = new BusConfDeviceTypeVO();
//构建数据
deviceTypeVO.setId(data.getId());
deviceTypeVO.setName(data.getDeviceType());
//子节点递归查找添加 传递父节点
deviceTypeVO.setChildren(getChildren(data.getId(),selectAll));
deviceTypeTree.add(deviceTypeVO);
});
}
return deviceTypeTree;
}
//递归获取children节点
private List<BusConfDeviceTypeVO> getChildren(String pid,List<BusConfDeviceType> list) {
//建立集合
List<BusConfDeviceTypeVO> children = new ArrayList<>();
//参数判空
if (StringUtils.isNotBlank(pid)){
list.forEach(data ->{
//若遍历的数据中的父节点id等于参数id
//则判定当前节点为该参数id节点下的子节点
if (pid.equals(data.getPid())){
//构造添加结果集合
BusConfDeviceTypeVO deviceTypeVO = new BusConfDeviceTypeVO();
deviceTypeVO.setId(data.getId());
deviceTypeVO.setName(data.getDeviceType());
children.add(deviceTypeVO);
}
});
}
//循环添加子菜单
//遍历children 集合
for (BusConfDeviceTypeVO deviceTypeVO : children) {
//创建查询对象
BusConfDeviceType paramsChildren = new BusConfDeviceType();
paramsChildren.setPid(deviceTypeVO.getId());
//查询该节点为父节点下的所有数据
List<BusConfDeviceType> result = this.deviceTypeMapper.select(paramsChildren);
//若该数据存在 添加集合到子节点中
//启用递归 继续探索叶子节点
if (result.size() > 0 && result != null) {
// 递归调用
deviceTypeVO.setChildren(getChildren(deviceTypeVO.getId(),list));
}
}
//若最后结果为空 则停止递归 返回值为null 赋予上级数据children属性
if (children.size() == 0) {
return null;
}
return children;
}
这样启动项目 利用postman 进行访问 可以得出如下结果
这样data中的数据就和组件所需要的数据相同了
之后完善前端页面 回填数据
html
<el-tree class="treeclass" ref="tree" :data="treeData" :props="defaultProps" @node-click="nodeclick" @check-change="handleClick" node-key="id" ></el-tree>
javascript
getdata() { //本人自定义方法
DeviceTypeList()//本人自定义方法
.then(res => {
console.log(JSON.stringify(res))
if (res.status == 200){
this.treeData = res.data;
this.$message({
type: 'success',
message: '数据加载成功!'
})
}
})
.catch(err => {
this.loading = false
this.$message.error('数据获取失败,请稍后再试!')
})
},
这样启动前端项目 访问后 控制台便可以打印出结果 格式化后与postman获取到的结果一致
页面效果如下