实现多级菜单的递归效果,我们可以使用 Vue.js 库来实现前端逻辑,Java 库来实现后端逻辑,也可以使用 Vue.js 的插件 Element UI 来实现前端部分。
下面是一些实现多级菜单递归效果的建议步骤:
步骤一:准备数据
在实现多级菜单递归效果前,需要准备好一组菜单数据。数据的结构大致如下:
[
{
"id": 1,
"name": "菜单1",
"parentId": 0
},
{
"id": 2,
"name": "菜单2",
"parentId": 0
},
{
"id": 3,
"name": "菜单3",
"parentId": 1
},
{
"id": 4,
"name": "菜单4",
"parentId": 1
},
{
"id": 5,
"name": "菜单5",
"parentId": 4
},
{
"id": 6,
"name": "菜单6",
"parentId": 2
}
]
其中 id
为菜单的唯一编号,name
为菜单名称,parentId
则是指向当前菜单的父级菜单的 ID,当 parentId
为 0 时表示为父级菜单。
步骤二:前端页面实现递归
使用 Vue.js 框架的时候,需要向 Vue 组件传递多级菜单数据,逐层递归渲染菜单,实现页面效果。
以 Element UI 为例,需要使用 el-cascader
组件实现多级选择,需要在页面 script 中进行如下设置:
export default {
data() {
return {
data: [], // 显示的多级菜单数据
options: [], // 多级菜单的配置项
defaultProps: {
children: 'children', // 配置项的 children 属性默认为 'children'
label: 'name', // 配置项的 label 属性默认为 'name'
}
}
},
mounted() {
// 请求数据
this.$http.get('/menu').then((res) => {
// 设置菜单数据
this.data = res.data;
// 包装菜单数据,为其添加 children 属性
const rootChildNodes = this.buildTreeWithChildren(res.data);
this.options = [{id: 0, name: '根节点', children: rootChildNodes}];
});
},
methods: {
// 包装菜单数据为带有 children 属性的节点
buildTreeWithChildren(list) {
const map = {};
const roots = [];
for (const node of list) {
node.children = []; // 为每个节点添加 children 属性
map[node.id] = node;
}
for (const node of list) {
const parent = map[node.parentId];
if (parent) {
parent.children.push(node);
} else {
roots.push(node);
}
}
return roots;
},
}
}
以上的代码会向服务器请求多级菜单数据,并且将其作为 data
属性的值进行更新。在页面的模板中,使用如下方法循环遍历每一个子菜单(包括子菜单的子菜单),从而达到递归遍历的效果:
<template>
<el-cascader
v-model="selectedItem"
:options="options"
:props="defaultProps"
clearable
placeholder="请选择分类"
@change="handleChange">
</el-cascader>
</template>
这里使用了 Element UI 的 el-cascader
组件实现了多级选择,其中 :options
属性用于设置多级菜单的配置项,:props
则用于设置配置项中的子属性名,:clearable
属性用于设置是否清除已选择的子选项,@change
属性用于监控子菜单选择的变化。
步骤三:后端实现递归
在服务端使用 Java 实现多级菜单的递归功能。可以参考以下示例代码:
@Service
public class MenuService {
@Autowired
private MenuMapper menuMapper;
@Transactional(rollbackFor = Exception.class)
public List<MenuDO> getMenuList() {
// 查询所有菜单的列表
List<MenuDO> menuList = menuMapper.selectMenuList();
// 构建树形菜单结构
return buildTree(menuList, 0L);
}
/**
* 构建多级菜单的树形结构
* @param menuList 菜单列表
* @param parentId 父级菜单 ID
* @return 构建完成的树形结构
*/
private List<MenuDO> buildTree(List<MenuDO> menuList, Long parentId) {
List<MenuDO> treeList = new ArrayList<>();
for (MenuDO menu : menuList) {
if (parentId.equals(menu.getParentId())) {
List<MenuDO> childList = buildTree(menuList, menu.getId());
menu.setChildList(childList);
treeList.add(menu);
}
}
return treeList;
}
}
在以上代码中,MenuMapper
是数据访问层的接口,MenuDO
则是数据实体类。
在 getMenuList()
方法中,使用菜单列表递归遍历每一个子菜单,将其转化为树形结构,返回构建成功的多级菜单数据。
步骤四:前后端联调
将前端页面通过路由链接到后端服务,并调用 getMenuList()
方法获取多级菜单的数据。从服务器返回的 JSON 数据中,可以看到父页菜单和各子页菜单的级别关系,这意味着 Vue 组件可以根据这些关系实现递归。给每个组件设置 label
属性,以表示菜单的名称,并设置菜单元素的 key
属性,从而保证可编辑的有效性。
多级菜单的递归实现,已经可以通过上述步骤实现。但要实现具有样式和交互性的多级菜单,则需要更多的工作。对元素的使用彻底掌握后,您可以通过以下一些额外的步骤添加样式:
- 创作可以缩进的子选项,使菜单树看起来更美观
- 通过视觉样式将父级选项和子选项区分开来,使用户可以轻松地识别每个节点
- 创造一个视觉响应,可以显示一个可见的验证标记,指示一个节点是打开还是关闭的
- 使用类似过渡和动画等视觉效果,使多级菜单看起来更具交互性。
实现多级菜单的递归效果并不难,关键在于数据和递归遍历,这是一项脱离 UI 实现的基础任务,因此,我们先要专注于如何在此阶段构建出具有正确结构和合适属性的多级菜单。管理组织得当,能够将项目分解成相对简单和可管理的部分,以便更容易地弄清楚繁琐的细节。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue+ java 实现多级菜单递归效果 - Python技术站