使用SpringBoot+Vue2完成文件树控件(Element-plus)

一、创建标准项目工程

注意:node.js版本要正确

以下都要管理员身份打开cmd窗口

若遇到创建项目的时候,出现卡顿不停,解决方案:

npm config set registry https://registry.npmmirror.com
npm config get registry #检查是否正确

创建myProject工程,使用vue模板:

npm init vite@latest myProject -- --template vue

进入创建的项目

cd .\myProject\

下载elemen-plus模板

npm install element-plus --save

进入项目的main.js下:

原始:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')

修改成:

注意:要先下载:element-plus

npm install element-plus
import { createApp } from 'vue'
  // 1.引入element - plus组件
  import ElementPlus from 'element-plus'
  import 'element-plus/dist/index.css'

  import './style.css'
  import App from './App.vue'

  const app = createApp(App);

  // 2.挂载到根节点
  app.use(ElementPlus);

  app.mount('#app');
二、Tree树形控件使用

Element-plus官网:Button 按钮 | Element Plus

去Element-plus官网找到对应的树形控件使用即可

选择自定义节点内容——这个有添加和删除,比较方便

将其代码复制放到前端项目工程即可(我的放在App.Vue)

项目需求只用到这个,上面部分没使用

<template>
  <div class="custom-tree-container">
    <el-tree
        :data="data"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <span>{{ node.label }}</span>
          <span>
            <a @click="append(data)"> + </a>
          </span>
        </span>
      </template>
    </el-tree>
  </div>
  <el-button @click="handleNodeClick">hello</el-button>
</template>

官网源代码的JS使用Vue3的可以直接使用和更改即可,我使用的是Vue2,所以直接自己改

因为是前后端分离项目,故需要下载axios

npm install axios

JS代码如下:

script>
import axios from 'axios';

export default {
  name: 'App',
  data() {
    return {
      data: [], // 数据
      label:{}, // 父亲节点对象
      defaultProps: {
        children: 'children',
        label: 'label',
      },
    };
  },
  created() {

  },
  methods: {
    handleNodeClick(data) {
      axios
          .get('http://localhost:8080/showNode', {
            params: {
              nodeId: data.label,
            },
          })
          .then((response) => {
            this.data = response.data.data
          })
          .catch((error) => {
            console.error(error);
          });
    },
    // 添加节点
    append(data) {
      // 获取弹框的值
      this.$prompt('请输入要添加的产品类型', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      }).then(({ value }) => {
        const newChild = {
          // 将弹框的值赋值给label,既节点名称
          label: value,
          fatherId: data.id // 添加节点时传递父节点的ID信息
        };
        axios
            .post('http://localhost:8080/addNode', newChild)
            .then((response) => {
              data.children.push(response.data.data);
              console.log(response)
            })
            .catch((error) => {
              console.error(error);
            });
      });
    },
  },
};
</script>

数据库结构如下:

对应的实体:

package com.example.demo.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.List;

/**
 * 节点实体
 */
@Data
public class Node {
    /**
     * 设置自动增长生产主键值
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 节点名称
     */
    private String label;
    /**
     * 父亲节点id
     */
    private Integer fatherId;
    @TableField(exist = false)
    /**
     * 孩子节点
     */
    private List<Node> children;
}

统一异常处理:

package com.example.demo.domain;

import lombok.Data;

/**
 * 统一异常处理
 *
 * @param <T>
 */
@Data
public class R<T> {
    /**
     * 响应编码
     */
    private String code;
    /**
     * 响应信息
     */
    private String msg;
    /**
     * 响应数据
     */
    private T data;

    /**
     * 请求成功
     */
    public static <T> R success(T data) {
        R<Object> objectR = new R<>();
        objectR.setCode("200");
        objectR.setMsg("请求成功");
        objectR.setData(data);
        return objectR;
    }

    /**
     * 请求失败
     *
     * @param <T>
     * @return
     */
    public static <T> R error() {
        R<Object> objectR = new R<>();
        objectR.setCode("500");
        objectR.setMsg("请求失败");
        return objectR;
    }
}

跨域问题解决:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 跨域问题解决
 */
@Configuration
public class CrosConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowCredentials(false)
                        .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                        .allowedOrigins("*");
            }
        };
    }
}

配置文件:

server:
  port: 8080
spring:
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/数据库名?serverTimezone=UTC
      username: 账户
      password: 密码

引入所需依赖:

<dependencies>
  <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
  </dependency>
  <dependency>
    <!--主要groupId是mysql-->
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
</dependencies>

数据访问层:

package com.example.demo.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.domain.Node;
import org.apache.ibatis.annotations.Mapper;

/**
 * 数据访问层
 */
@Mapper
public interface NodeMapper extends BaseMapper<Node> {
}

业务逻辑层:

package com.example.demo.service;


import com.example.demo.domain.Node;
import com.example.demo.domain.R;
import com.fasterxml.jackson.core.JsonProcessingException;

import java.util.List;

public interface NodeService {
    /**
     * 展示节点
     *
     * @return
     */
    R showNode();

    /**
     * 添加节点
     *
     * @param node
     * @return
     */
    R addNode(Node node);
}
package com.example.demo.service.impl;

import com.example.demo.dao.NodeMapper;
import com.example.demo.domain.Node;
import com.example.demo.domain.R;
import com.example.demo.service.NodeService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;

/**
 * 业务逻辑层
 */
@Service
public class NodeServiceImpl implements NodeService {
    @Autowired
    private NodeMapper nodeMapper;

    /**
     * 展示节点信息
     *
     * @return
     */
    @Override
    public R showNode() {
        List<Node> nodes = nodeMapper.selectList(null);
        // 有fatherId的节点,走递归
        LinkedList<Node> childNode = new LinkedList<>();
        // 所有的节点
        LinkedList<Node> allNode = new LinkedList<>();
        // 遍历节点
        for (Node node : nodes) {
            if (node.getFatherId().equals(0)) {
                allNode.add(node);
            } else {
                childNode.add(node);
                allNode.add(node);
            }
        }
        List<Node> nodes1 = forEach(childNode, allNode);
        LinkedList<Node> allNodes = new LinkedList<>();
        for (Node node : nodes1) {
            if (node.getFatherId().equals(0)) {
                allNodes.add(node);
            }
        }
        return R.success(allNodes);
    }

    /**
     * 添加节点信息
     *
     * @param node
     * @return
     */
    @Override
    public R addNode(Node node) {
        int insert = nodeMapper.insert(node);
        if (insert > 0) {
            return R.success(node);
        }
        return R.error();
    }


    // 遍历所有节点的孩子
    public List<Node> forEach(List<Node> childNode, List<Node> allNode) {
        // 遍历所有节点
        for (Node node : allNode) {
            LinkedList<Node> childs = new LinkedList<>();
            // 遍历所有有fatherId的节点
            for (Node node1 : childNode) {
                // 如果孩子节点的fatherId与节点的Id相同,则为其孩子
                if (node1.getFatherId().equals(node.getId())) {
                    // 将该节点添加为孩子节点
                    childs.add(node1);
                }
            }
            // 将孩子集合设为节点的孩子集合
            node.setChildren(childs);
        }
        return allNode;
    }
}

控制层:

package com.example.demo.controller;

import com.example.demo.domain.Node;
import com.example.demo.domain.R;
import com.example.demo.service.NodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
public class NodeController {
    @Autowired
    private NodeService nodeService;

    @GetMapping("/showNode")
    R nodeShow() {
        R r = nodeService.showNode();
        return r;
    }

    @PostMapping("/addNode")
    R addNode(@RequestBody Node node) {
        R r = nodeService.addNode(node);
        return r;
    }
}

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值