有两种方案,一种是前端转,一种是后端转,一般都是后端转
数据模型如下:一个List集合
//java传过来一个集合
[
Menu(id=1, name=首页1, pid=0),
Menu(id=2, name=首页2, pid=0),
Menu(id=3, name=菜单1, pid=1),
Menu(id=4, name=菜单2, pid=1),
Menu(id=5, name=菜单3, pid=2),
Menu(id=6, name=子项1, pid=3),
Menu(id=7, name=子项2, pid=3),
Menu(id=8, name=子项3, pid=4)
]
前端转换方案如下
<template>
<div>
<div class="block">
<span class="demonstration">hover 触发子菜单</span>
<el-cascader v-model="value" :options="options" :props="{ expandTrigger: 'hover' }"
@change="handleChange"></el-cascader>
</div>
</div>
</template>
<script>
import axios from '../util/myaxios'
export default {
async mounted() {
let resp = await axios.get('api/menu');
//console.log(resp.data.data);
const array = resp.data.data;
const map = new Map();
//1.把所有数据存入map集合(为了接下来查找效率)
for(const ops of array){
map.set(ops.id,{value:ops.id,label:ops.name,pid:ops.pid})
}
//2.建立父子关系
//3.找到顶层对象
const top = [];
for(const obj of map.values()){
const parent = map.get(obj.pid);
if (parent !== undefined) {
parent.children ??=[];
parent.children.push(obj);
}else{
top.push(obj);
}
}
console.log(top);
this.options = top;
},
data() {
return {
value:'',
options:[]
}
},
methods: {
handleChange(value) {
console.log(value);
}
}
}
</script>
<style>
</style>
后端转换方案如下:
Map<Integer, Map<String, Object>> map = new HashMap<>();
//1.把所有数据存入map集合(为了接下来查找效率)
for (Menu menu : menus) {
Map<String, Object> mapValue = new HashMap<>();
mapValue.put("value", menu.getId());
mapValue.put("label", menu.getName());
mapValue.put("pid", menu.getPid());
map.put(menu.getId(), mapValue);
}
//2.建立父子关系
//3.找到顶层对象
List<Map<String, Object>> top = new ArrayList<>();
for (Map.Entry<Integer, Map<String, Object>> entry : map.entrySet()) {
Map<String, Object> obj = entry.getValue();
Map<String, Object> parent = map.get(obj.get("pid"));
if (parent != null) {
List<Map<String, Object>> children = (List<Map<String, Object>>) parent.get("children");
if (children == null) {
children = new ArrayList<>();
parent.put("children", children);
}
children.add(obj);
} else {
top.add(obj);
}
}
return R.success(top);