springboot + vue 实现递归生成多级菜单(实例代码)

下面我将为您详细讲解“springboot + vue 实现递归生成多级菜单”的完整攻略。

简介

本文将介绍如何使用SpringBoot和Vue.js实现递归生成多级菜单。通过该方案,可以生成任意深度的多级菜单。

准备工作

在开始之前,需要下载安装以下软件:

  • JDK 8+
  • Node.js
  • Vue CLI

创建SpringBoot项目

首先,使用Spring Initializr创建一个新的SpringBoot项目,具体方法可以参考官方文档

在创建过程中,需要添加以下依赖项:

  • Spring Web
  • Spring Data JPA
  • MySQL Driver

创建完成后,将生成的代码导入到你的IDE中并进行配置。

创建数据库表

创建一个名为sys_menu的数据库表,用于存储菜单数据。

表结构如下:

CREATE TABLE `sys_menu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父菜单ID,一级菜单为0',
  `name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
  `url` varchar(200) DEFAULT NULL COMMENT '菜单URL',
  `perms` varchar(500) DEFAULT NULL COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
  `type` int(11) DEFAULT NULL COMMENT '类型   0:目录   1:菜单   2:按钮',
  `order_num` int(11) DEFAULT NULL COMMENT '菜单排序',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

编写SpringBoot代码

下一步是编写SpringBoot后端代码。在com.example.demo包下创建一个名为controller的包,并在其中创建一个名为MenuController的控制器。

@RestController
@RequestMapping("/menu")
public class MenuController {

    @Autowired
    private MenuService menuService;

    @GetMapping("/list")
    public List<Menu> list() {
        return menuService.list();
    }
}

com.example.demo包下创建一个名为service的包,并在其中创建一个名为MenuService的服务。

public interface MenuService {
    List<Menu> list();
}

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuRepository menuRepository;

    @Override
    public List<Menu> list() {
        // 递归查询所有菜单
        List<Menu> menuList = menuRepository.findByParentIdIsNull();
        return build(menuList);
    }

    /**
     * 递归生成菜单树
     * @param menuList 菜单列表
     * @return 生成的菜单树
     */
    private List<Menu> build(List<Menu> menuList) {
        List<Menu> treeList = new ArrayList<>();

        for (Menu menu : menuList) {
            if (menu.getType() == 0) {
                // 递归查询子菜单
                List<Menu> children = menuRepository.findByParentId(menu.getId());
                menu.setChildren(build(children));
            }

            treeList.add(menu);
        }

        return treeList;
    }
}

最后,在com.example.demo包下创建一个名为repository的包,并在其中创建一个名为MenuRepository的仓库。

public interface MenuRepository extends JpaRepository<Menu, Long> {

    /**
     * 按 parentId 查找菜单
     */
    List<Menu> findByParentId(Long parentId);

    /**
     * 查找 parentId 为 null 的菜单
     */
    List<Menu> findByParentIdIsNull();
}

创建Vue前端项目

在命令行中执行如下命令,创建一个名为vue-demo的新项目:

vue create vue-demo

该命令会使用Vue CLI创建一个新的Vue.js项目,并自动安装所需的依赖项。

编写Vue代码

vue-demo项目中,打开src/App.vue文件,修改其内容如下:

<template>
  <div>
    <h1>{{ title }}</h1>
    <ul>
      <menu-item v-for="menu in menuList" :key="menu.id" :menu="menu"></menu-item>
    </ul>
  </div>
</template>

<script>
import axios from 'axios'
import MenuItem from './components/MenuItem.vue'

export default {
  name: 'App',
  components: {
    MenuItem
  },
  data() {
    return {
      title: '递归生成多级菜单',
      menuList: []
    }
  },
  created() {
    // 加载菜单数据
    axios.get('/menu/list').then(response => {
      this.menuList = response.data
    })
  }
}
</script>

该代码会渲染一个多级菜单,其数据来源于后端控制器。

vue-demo项目中,创建一个名为components的目录,并在其中创建一个名为MenuItem.vue的组件。

<template>
  <li>
    <a v-if="menu.type === 1" :href="menu.url">{{ menu.name }}</a>
    <span v-else>{{ menu.name }}</span>

    <ul v-if="menu.children">
      <menu-item v-for="child in menu.children" :key="child.id" :menu="child"></menu-item>
    </ul>
  </li>
</template>

<script>
export default {
  name: 'MenuItem',
  props: {
    menu: {
      type: Object,
      required: true
    }
  }
}
</script>

该组件会渲染一个菜单项,并递归渲染其子菜单项。

运行程序

在命令行中,分别进入springbootvue-demo目录,并执行以下命令:

// 在springboot目录下执行以下命令
./mvnw spring-boot:run

// 在vue-demo目录下执行以下命令
npm run serve

现在,您就可以在浏览器中访问http://localhost:8080,查看漂亮的多级菜单了!

示例说明

示例1:添加菜单

为了演示添加菜单的操作,可以修改MenuControllerlist()方法的返回值,返回一个由多个菜单项组成的“菜单列表”。具体代码如下:

@GetMapping("/list")
public List<Menu> list() {
    List<Menu> menuList = new ArrayList<>();

    // 添加第一个菜单项
    Menu menu1 = new Menu();
    menu1.setId(1L);
    menu1.setName("系统管理");
    menu1.setUrl(null);
    menu1.setType(0);
    menu1.setOrderNum(10);
    menu1.setCreateTime(new Date());
    menu1.setUpdateTime(new Date());

    Menu menu11 = new Menu();
    menu11.setId(11L);
    menu11.setName("用户管理");
    menu11.setUrl("/user");
    menu11.setType(1);
    menu11.setOrderNum(10);
    menu11.setCreateTime(new Date());
    menu11.setUpdateTime(new Date());

    Menu menu12 = new Menu();
    menu12.setId(12L);
    menu12.setName("角色管理");
    menu12.setUrl("/role");
    menu12.setType(1);
    menu12.setOrderNum(20);
    menu12.setCreateTime(new Date());
    menu12.setUpdateTime(new Date());

    // 第一个菜单项添加两个子菜单项
    menu1.setChildren(Arrays.asList(menu11, menu12));

    // 添加第二个菜单项
    Menu menu2 = new Menu();
    menu2.setId(2L);
    menu2.setName("购物中心");
    menu2.setUrl("/shop");
    menu2.setType(1);
    menu2.setOrderNum(20);
    menu2.setCreateTime(new Date());
    menu2.setUpdateTime(new Date());

    menuList.add(menu1);
    menuList.add(menu2);

    return menuList;
}

示例2:删除菜单

为了演示删除菜单的操作,可以在MenuServiceImpl中添加一个名为delete()的方法,实现删除菜单的功能。具体操作如下:

public void delete(Long id) {
    // 从数据库中删除菜单
    menuRepository.deleteById(id);
}

MenuController中添加一个名为delete()的方法,实现删除菜单项的功能。具体代码如下:

@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
    menuService.delete(id);
}

MenuItem.vue组件中添加一个名为delete()的方法,实现“删除菜单”按钮的功能。具体代码如下:

<template>
  <li>
    <div>
      <a v-if="menu.type === 1" :href="menu.url">{{ menu.name }}</a>
      <span v-else>{{ menu.name }}</span>

      <button v-if="menu.type !== 0" @click="deleteMenu">删除</button>
    </div>

    <ul v-if="menu.children">
      <menu-item v-for="child in menu.children" :key="child.id" :menu="child"></menu-item>
    </ul>
  </li>
</template>

<script>
export default {
  name: 'MenuItem',
  props: {
    menu: {
      type: Object,
      required: true
    }
  },
  methods: {
    deleteMenu() {
      if (window.confirm('确认删除该菜单?')) {
        // 向后台发送删除请求
        axios.delete('/menu/' + this.menu.id)
        // 重新加载菜单数据
        this.$root.$emit('reloadMenu')
      }
    }
  }
}
</script>

将“删除菜单”按钮添加到菜单项中之后,就可以轻松删除菜单项了!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot + vue 实现递归生成多级菜单(实例代码) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • python查找特定名称文件并按序号、文件名分行打印输出的方法

    要查找特定名称的文件并按照序号、文件名分行打印输出,我们可以使用Python中的os和re模块提供的功能。 以下是详细的步骤: 导入必要模块 首先,我们需要导入两个模块:os和re。os模块将帮助我们搜索目录中的文件,而re模块将帮助我们匹配特定名称文件。 import os import re 定义文件名模式 接下来,我们需要定义文件名模式。为此,我们可以…

    other 2023年6月27日
    00
  • html-定位:after伪元素

    HTML定位:after伪元素的完整攻略 在HTML中,我们可以使用:after伪元素来为元素添加额外的内容,并使用定位属性来控制其位置。本文将介绍如何使用:after伪元素进行定位,并提供两个示例说明。 骤1:创建HTML元素 首先,我们需要创建一个HTML元素,以便为其添加:after伪元素。可以按照以下步骤创建元: <div class=&quo…

    other 2023年5月8日
    00
  • es批量更新与新增(elasticsearch)

    Elasticsearch批量更新与新增攻略 Elasticsearch是一个开源的分布式搜索和分析引擎,可以帮助我们快速地存储、搜索和分析大量数据。本攻略将介绍如何使用Elasticsearch进行批量更新和新增操作。 步骤一:准备数据 在进行批量更新和新增操作之前,我们需要准备好要更新或新增的数据。以下是一个示例,展示了如何使用Python生成一些测试数…

    other 2023年5月9日
    00
  • SQLite 入门教程一 基本控制台(终端)命令

    SQLite 入门教程一 基本控制台(终端)命令 简介 SQLite 是一款轻量级的关系型数据库,由于其功耗低、体积小、易于管理等特点,被广泛应用于移动应用、嵌入式系统等场景中。本文将从命令行的角度出发,介绍 SQLite 的基本用法。 安装 SQLite Windows 平台 推荐在 Windows 平台下使用 SQLite tools for Windo…

    other 2023年6月26日
    00
  • Python入门必读的if语句嵌套方法

    Python入门必读的if语句嵌套方法攻略 在Python编程中,if语句嵌套是一种非常有用的技术,它允许我们根据不同的条件执行不同的代码块。本攻略将详细介绍if语句嵌套的基本概念和用法,并提供两个示例说明。 基本概念 if语句嵌套是指在一个if语句的代码块中再嵌套另一个if语句。这种嵌套结构可以根据多个条件进行判断,并根据不同的条件执行相应的代码块。if语…

    other 2023年7月27日
    00
  • jquery绑定input的change事件

    jQuery绑定input的change事件 在Web开发中,我们经常需要使用jQuery绑定input的change事件,以便在输入框内容发生变化时执行一些操作。以下是jQuery绑定input的change事件的完整攻略。 步骤 以下是jQuery绑定input的change事件的步骤: 使用jQuery选择器选择要绑定change事件的input元素。…

    other 2023年5月6日
    00
  • eclipse配置环境变量

    以下是“Eclipse配置环境变量的完整攻略”的详细讲解,过程中包含两个示例说明的标准Markdown格式文本: Eclipse配置环境变量的完整攻略 Eclipse是一款常用的Java开发工具,为了够在Eclipse中正常使用Java开发,需要配置Java环境变量。以下是Eclipse配置环境变量的详细步骤: . 配置JAVA_HOME环境变量 在Wind…

    other 2023年5月10日
    00
  • mysql中cast()

    MySQL中Cast() 函数 在MySQL中,Cast()函数是一种数据类型转换函数,用于将一个数据类型转换成另一个数据类型,根据需求可以将一个字符串转为数值、日期转换为字符串等等。 Cast() 函数语法 Cast() 函数的基本语法如下所示: CAST(expr AS type) 其中,expr 代表需要进行类型转换的表达式或字段,type 是需要转换…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部