后端转换为树形结构
public class Menu implements Serializable {
/**
* 菜单ID
*/
@TableId(value = "id")
private String id;
/**
* 父菜单ID
*/
@TableField(value = "parent_id")
private String parentId;
//存放子菜单的集合属性,用于存放子菜单行数据
@TableField(exist = false)
List<Menu> children;
}
public List<Menu> tree() {
//获取数据库中的菜单列表
List<Menu> list = this.list();
ArrayList<Menu> tree = new ArrayList<>();
for(Menu menu : list){
/**
* 判断菜单数据中的父菜单id属性
* 1.如果当前菜单它的父菜单id属性值为0或null
* 表示当前菜单数据为根节点数据, 把它存放在树形数据集合中
* 2.如果当前菜单它的父菜单id属性值不为null也不为0
* 表示当前数据不是根节点数据,它是子节点数据.
* 需要找到当前数据的父节点数据,将当前数据添加到父节点中(父节点中所有一个属性children集合,子节点集合)
*/
if(menu .getParentId() == null || "0".equals(menu .getParentId())){
tree.add(menu );
}else{
for(Menu parentMenu : list){
//将外部菜单行对象的父id与上面遍历的菜单行对象id进行比较看是不是它的子
if(menu.getParentId().equals(parentMenu.getId())){
//如果是判断菜单中的List<Menu>属性是否为空
if(parentMenu.getChildren() == null){
parentMenu.setChildren(new ArrayList<>());
}
parentMenu.getChildren().add(menu);
}
}
}
}
return tree;
}
前端转化为树形结构
export function dataToTree (data, id = 'id', parentId = 'parentId', children = 'children') {
// 定义一个数组接收数据
var res = []
//遍历数据库中的每一行菜单数据
for (let i = 0; i < data.length; i++) {
let node = data[i]
//判断当前菜单行是否为根节点,不是不进入循环
if (node[parentId] && node[parentId] != '0') {
//从头遍历菜单行数据
for (let j = 0; j < data.length; j++) {
let treeNode = data[j]
//判断当前菜单行的id是否为外部菜单行的父id
if (node[parentId] == treeNode[id]) {
//如果是外部菜单行的父id则再判断其children属性是否存在,不存在创建一个空数组
if (!treeNode[children]) {
treeNode[children] = []
}
//将外部菜单对象放进当前菜单的children属性中
treeNode[children].push(node)
}
}
} else { //当前节点是根节点,直接放入数组中
res.push(node)
}
}
return res
}