思路:定义一个递归前端组件tree-table,在每个组件中先渲染左侧item的数据,然后再在右侧遍历item的children,其中每次遍历都创建一个tree-table,最终这个纵向表头的树形表格就可以被动态渲染出来了!
注意:由于我们是递归组件渲染表格,因此应该让父容器被子元素自动撑开,所以给所有父容器加入overflow:auto属性,否则渲染完成后加入边框div之间会有很难看的缝隙!
1.首先准备树形数据格式如下:
{ "nid": 0, "nname": "测试", "parent": 0, "children": [ { "nid": 57, "nname": "测试分支1", "parent": -1, "children": [ { "nid": 59, "nname": "测试叶子1", "parent": 57, "children": null }, { "nid": 479, "nname": "测试叶子2", "parent": 57, "children": null } ] }, { "nid": 58, "nname": "测试树根2", "parent": -1, "children": [ { "nid": 60, "nname": "测试叶子3", "parent": 58, "children": null } ] } ] }
2.tree-table代码如下:
<template>
<div style="display: flex;flex-direction: row;font-weight: 300;overflow: auto;">
<div style="display: flex;width: 200px;justify-content: center;align-items: center;border: solid 1px lightgray;float: left;flex-shrink: 0;">
<div v-if="data.nname" style="display: flex;justify-content: center;align-items: center;">{{data.nname}}</div>
<div v-else style="display: flex;justify-content: center;align-items: center;">/</div>
</div>
<div style="display: flex;flex-direction: column;margin: 0;padding: 0;">
<tree-table v-for="item in data.children" :data="item"></tree-table>
</div>
</div>
</template>
<script>
export default {
name: "TreeTable", // 组件命名
}
</script>
<script setup>
import {defineProps} from 'vue'
const prop = defineProps({
data:Object
})
</script>
<style scoped>
div{
margin: 0;
padding: 0;
}
</style>
3.tree-table组件在页面中的使用方法:
(先在页面中import引入tree-table组件,再使用:data给tree-table组件传数据)
<div style=" margin: 0; padding: 0;overflow: auto;">
<tree-table :data="TreeTableData" style="border: solid 1px lightgray;padding: 0;margin: 0;overflow: auto;">
</tree-table>
</div>
4.看效果
5.数据在数据库中的存储
每个元素需要存nid(结点ID),nname(结点名),parent(父节点ID)三个字段
然后在后端将结点列表构造成树或森林的形式,转换为第一步中的数据json,发送给前端即可。
6.后端:List<Node>转换为树的算法(伪代码)
public List<NodeTree> convertTree(List<NodeTree> list) {
List<NodeTree> trees = new ArrayList<>();
for (list的每个元素item) {
if (item.getParent()==-1) {
将item加到tress中;//item为树根
}
for (list的每个元素childItem) {
if (childItem是item的父亲) {
if (item无孩子) {
item.setChildren(new ArrayList<NodeTree>());
}
item.getChildren().add(childItem);
}
}
}
return trees;
}