有两种方案,一种是前端转,一种是后端转,一般都是后端转
数据模型如下:一个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);