vue elementui+jdk1.8实现多级菜单

vue elementui+jdk1.8实现多级菜单

  • 前言:在学习谷粒商城的时候,在做分类维护树形菜单维护的功能中,项目中只讲了菜单三级树怎么实现,想拓展一下多级菜单,功能已实现,记录一下,有不对的地方欢迎指正。

一、后端部分

使用Jdk1.8的新特性Stream和lamada表达式,数据库的框架使用苞米豆的mybatis plus,话不多说,上代码

1. 新建ManyTree类,可封装成工具类

import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
public class ManyTree {

    private List<CategoryEntity> rootList; // 根节点对象存放到这里
    private List<CategoryEntity> bodyList; // 其他节点存放到这里,可以包含根节点

    public ManyTree(List<CategoryEntity> rootList, List<CategoryEntity> bodyList) {
        this.rootList = rootList;
        this.bodyList = bodyList;
    }

    public List<CategoryEntity> getTree() { // 调用的方法入口
        if (bodyList != null && !bodyList.isEmpty()) {
            // 声明一个map,用来过滤已操作过的数据
            Map<String, String> map = Maps.newHashMapWithExpectedSize(bodyList.size());
            rootList.forEach(beanTree -> getChild(beanTree, map));
            return rootList;
        }
        return null;
    }

    public void getChild(CategoryEntity beanTree, Map<String, String> map) {
        List<CategoryEntity> childList = Lists.newArrayList();
        bodyList.stream().filter(c -> !map.containsKey(c.getCatId())).filter(c -> c.getParentCid().equals(beanTree.getCatId()))
                .forEach(c -> {
                    map.put(String.valueOf(c.getCatId()), String.valueOf(c.getParentCid()));
                    getChild(c, map);
                    childList.add(c);
                });
        beanTree.setChildren(childList);
    }

}

2. 新建实体CategoryEntity,这里用了lombok,idea安装lombok插件,项目添加lombok的依赖,详细自行百度

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
/**
 * 商品分类
 * 
 */
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
	private static final long serialVersionUID = 1L;
	/**
	 * 主键id
	 */
	@TableId
	private Long catId;
	/**
	 * 菜单名称
	 */
	private String name;
	/**
	 * 父级菜单ID
	 */
	private Long parentCid;
	/**
	 * 层级,1 2 3层
	 */
	private Integer catLevel;
	/**
	 * 展示状态,可用作逻辑删除
	 */
	private Integer showStatus;
	/**
	 * 排序字段
	 */
	private Integer sort;
	/**
	 * 展示图标
	 */
	private String icon;
	private String productUnit;
	private Integer productCount;
	//这个注解的含义是在数据库表中不存在
	/**
	 * 用于装载子菜单children
	 */
	@TableField(exist=false)
	private List<CategoryEntity> children;
}

3. 业务层新建service,这里只贴service实现层的代码

    /**
     * 递归查询树形菜单数据逻辑已经抽取出来,
     * 这里只需要传入两个数据集合即可:1、所有菜单数据,包括根节点以及子节点 2、所有一级菜单数据
     * @return
     */
    @Override
    public List<CategoryEntity> getAllTree() {
        //使用mybatis-plus自带的baseMapper.selectList方法查询出所有
        List<CategoryEntity> bodyList = baseMapper.selectList(null);
        //使用xml查询出所有一级菜单
        List<CategoryEntity> rootList = categoryDao.getRootTree();
        ManyTree utils = new ManyTree(rootList, bodyList);
        List<CategoryEntity> result = utils.getTree();
        return result;
    }

二、前端部分

1. Category.vue

<template>
  <div class>
    <el-tree
      :data="menus"
      :props="defaultProps"
      :expand-on-click-node="false"
      node-key="catId"
      ref="menuTree"
      :show-checkbox="showCheckbox"
    >
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button  type="text"  size="mini" @click="() => append(data)">增加</el-button>
          <el-button  type="text"  size="mini" @click="() => edit(data)">修改</el-button>
          <el-button
            v-if="node.childNodes.length==0"
            type="text"
            size="mini"
            @click="() => remove(node, data)"
          >删除</el-button>
        </span>
      </span>
    </el-tree>
  </div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {
      //菜单栏数据
      menus: [],
      defaultProps: {
		//与后端实体中封装的子节点名称对应
        children: "children",
        label: "name"
      },
      showCheckbox:true
    };
  },
  //监听属性 类似于data概念
  computed: {},
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    // 获取菜单数据
    getMenus() {
      this.$http({
        url: this.$http.adornUrl("/product/category/list/tree"),
        method: "get"
      }).then(({ data }) => {
        //console.log("获取菜单数据的data:" + data.data);
        this.menus = data.data;
      });
    },
    edit(data){
    },
    append(data) {   
    },
    //移除节点方法
    remove(node, data) { 
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {
    this.getMenus();
  },
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {},
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style lang='scss' scoped>
//@import url(); 引入公共css类
</style>

2. 展示效果
在这里插入图片描述

三、数据库

1. 建表sql

CREATE TABLE `pms_category` (
  `cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
  `name` char(50) DEFAULT NULL COMMENT '分类名称',
  `parent_cid` bigint(20) DEFAULT NULL COMMENT '父分类id',
  `cat_level` int(11) DEFAULT NULL COMMENT '层级',
  `show_status` tinyint(4) DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `icon` char(255) DEFAULT NULL COMMENT '图标地址',
  `product_unit` char(50) DEFAULT NULL COMMENT '计量单位',
  `product_count` int(11) DEFAULT NULL COMMENT '商品数量',
  PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1450 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类';

2. 模拟数据
可以自己造些数据,有需要的数据可以云盘拿,懒得摘了!
链接:https://pan.baidu.com/s/1m3vwDqPDXYLKKJ8AN9I14w
提取码:0os7

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值