电商项目——商品服务-API-三级分类——第九章——上篇

本文档详细介绍了电商项目中商品服务的三级分类API开发过程,包括查询递归树形结构获取数据、配置网关路由与路径重写、统一配置跨域、查询树形展示数据、删除及修改功能的实现。通过一系列步骤,实现了后台管理系统对三级分类的增删改查,并解决了跨域问题,完成了前端显示和交互功能。
摘要由CSDN通过智能技术生成

电商项目——初识电商——第一章——上篇
电商项目——分布式基础概念和电商项目微服务架构图,划分图的详解——第二章——上篇
电商项目——电商项目的虚拟机环境搭建_VirtualBox,Vagrant——第三章——上篇
电商项目——Linux虚拟机中安装docker,mysql,redis_VirtualBox——第四章——上篇
电商项目——电商项目的环境搭建_开发工具&环境搭建——第五章——上篇
电商项目——快速开发人人开源搭建后台管理系统&代码生成器逆向工程搭建——第六章——上篇
电商项目——分布式组件(SpringCloud Alibaba,SpringCloud)——第七章——上篇
电商项目——前端基础——第八章——上篇
电商项目——商品服务-API-三级分类——第九章——上篇
电商项目——商品服务-API-品牌管理——第十章——上篇
电商项目——商品服务-API-属性分组——第十一章——上篇
电商项目——商品服务-API-品牌管理——第十二章——上篇
电商项目——商品服务-API-平台属性——第十三章——上篇
电商项目——商品服务-API-新增商品——第十四章——上篇
电商项目——商品服务-API-商品管理——第十五章——上篇
电商项目——商品服务-API-仓库管理——第十六章——上篇

讲完了前面几章的内容,现在我们就可以对后台管理系统,和微服务项目进行开发了,我们先从三级分类说起
默认mall-product的环境已经全部配置好了

1:查询-递归树形结构获取数据

在这里插入图片描述
三级分类(电商里面经常用到的功能):所有的数据都是来源于数据库,我们要对三级分类进行维护,进行增删改查,我们首先就必须要后台管理系统来可以维护我们的整个数据。所以我们引出了下面的问题,解决了下面问题,我们就可以在搭建前端界面进行前后端连接

问题:如何查出所有三级分类以及子分类,并以树形结构组装起来?,我们看这篇的思路分析
电商项目——如何查出所有三级分类,并以树形结构组装起来?

2:配置网关路由与路径重写

接下来我们来编写后台管理系统的前端项目,来维护三级分类的增删改查

我们先进行测试看是否后台管理系统可以成功启动
启动renren-fast和renren-fast-vue
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一步:我们要写商品系统的相关内容,看如下操作
在这里插入图片描述
跟商品系统有关的项目都放在我自己新增的商品系统目录下,然后我们在商品系统的目录下,增加一个菜单
在这里插入图片描述
最终的效果如下
在这里插入图片描述
搭建分类维护功能,我们期望展示出整个三级分类,然后可以对三级分类进行增删改查,而我们想要做这个功能,就要先了解脚手架工程的一些基本规范
在这里插入图片描述
脚手架工程的基本规范1:
在这里插入图片描述
脚手架工程的基本规范2:
在这里插入图片描述

第二步:在renren-fast-vue中搭建分类维护路径的对应目录如下,并进行前端显示三级分类数据的搭建
在这里插入图片描述
我们就可以在category中使用ElementUI进行前端显示三级分类数据的搭建

第三步:在renren-fast-vue中的src/views/modules/product/路径下搭建category.vue

我们使用ElementUI组件中的Tree树形控件来完成我们的功能,并且还要向后端发送请求在返回数据给前端
代码如下

<template>
  <!--label	指定节点标签为节点对象的某个属性值,,children	指定子树为节点对象的某个属性值,,,data	展示数据-->
  <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>

<script>
    export default {
        // import引入的组件需要注入到对象中才能使用",
      components: {},
      data () {
            // 这里存放数据",
        return {
            data: [],
            defaultProps: {
              children: 'children',
              label: 'label'
            }
        }
       },
        // 方法集合",
      methods: {
        // 获取数据列表
        getDataList () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'

          }).then(({data}) => {
            console.log("成功获取到菜单数据:"+data)

          })
        }
      },
        // 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
      created () {
        this.getDataList();
      }
    }
    </script>

我们进行测试
在这里插入图片描述
解决办法:我们要改变基本路径http://localhost:8080/renren-fast的值把它变成网关的基本路径(我们以后要上线很多微服务项目,我们不肯能一直去renren-fast-vue中一直修改基本路径的端口,所以我们把所有的请求发送给网关,网关在分配到指定的路径的微服务中)
在这里插入图片描述
在进行测试,发现下面问题
在这里插入图片描述
解决办法:把renren-fast注册到注册中心中,并且配置网关的routes
renren-fast

  1. 引入mall-common依赖
		<dependency>
			<groupId>com.atstudying.mall</groupId>
			<artifactId>mall-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
  1. 编译application.yml配置
spring:
  application:
    name: renren-fast
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  1. 导入@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class RenrenApplication {
   

	public static void main(String[] args) {
   
		SpringApplication.run(RenrenApplication.class, args);
	}

}
  1. mall-gateway中
    配置网关的routes
    在这里插入图片描述
    在进行测试,发现下面问题
    在这里插入图片描述
    解决办法:重新配置好网关的路由,新增一个路径重写功能
    mall-gateway
    在这里插入图片描述
    在进行测试:发现如下问题
    在这里插入图片描述

从8001访问到88出现了跨域问题,默认拒绝跨域请求

我们下一章就来介绍如何解决跨域问题

3:网关统一配置跨域

上一小节,我们配置了网关路由和路径重写(renren-fast),我们的验证码也刷新出来了,但是我们在登录测试的时候,发现报了一个跨域的问题
什么是跨域呢?怎么解决跨域问题呢?下面这篇文章为大家一一解答

HTTP访问控制(CORS)——预检请求问题的解决
上面这篇文章的第四节就是解决网关统一配置跨域的一个案例演示

我们根据上面这篇文章成功解决跨域问题后,再次登录,发现登录,发现还是登录不了,进行检查,发现下面问题
在这里插入图片描述
解决办法:renren-fast中注释掉有关跨域的代码
在这里插入图片描述
重新启动renren-fast,并重新登录,发现登录成功

4:查询-树形展示三级分类数据

上节我们解决了跨域,我们现在来继续编写商品系统目录下分类维护菜单的代码
在这里插入图片描述
我么刷新上面界面,并检查元素发现,跨域问题解决了,可是请求却找不到
在这里插入图片描述
解决办法,我么以前配置网关路由默认是全部转到renren-fast的,所以我们的请求找不到,我们现在去网关配置一个mall-product的网关路由,让请求跳转到该路由下。
在这里插入图片描述
我们进行如下测试,发现数据成功获取
http://localhost:88/api/product/category/list/tree
如上的地址经过网关会变成如下地址
http://localhost:30000/product/category/list/tree
因为,我们配置的网关路由在起作用,如上两个地址的访问都会得到下面的图的效果

      - id: mall-product
        uri: lb://mall-product
        predicates:
          - Path=/api/product/**
        filters:
          - RewritePath=/api/(?<segment>.*),/$\{
   segment}  

在这里插入图片描述
我们看见数据已经成功返回给了前端界面,可是我们要怎么展示呢?
在这里插入图片描述
category.vue

 methods: {
        handleNodeClick(data){
          console.log(data)
        },
        // 获取数据列表
        getDataList () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'

          }).then( data => {
            console.log("成功获取到菜单数据:"+data)

          })
        }
      created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
        this.getDataList();
      },

我们发现data中有很多属性,可是我们要的数据是在data.data中,所以我们可以在前端的category.vue中进行项目解构
在这里插入图片描述
如下category.vue中部分代码演示片段({data})(解构)

  // 获取数据列表
        getDataList () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'

          }).then( ({data}) => {
            console.log("成功获取到菜单数据:"+data.data)
          })
        }

完整的代码如下
category.vue

<template>
  <!--label	指定节点标签为节点对象的某个属性值,,children	指定子树为节点对象的某个属性值,,,data	展示数据-->
  <el-tree :data="menus" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>

<script>
    export default {
        // import引入的组件需要注入到对象中才能使用",
      components: {},
      data () {
            // 这里存放数据",
        return {
            menus: [],
            defaultProps: {
              children: 'children',
              label: 'name'
            }
        }
       },
        // 监听属性 类似于data概念",
      computed: {},
        // 监控data中的数据变化",
      watch: {},
        // 方法集合",
      methods: {
        handleNodeClick(data){
          console.log(data)
        },
        // 获取数据列表
        getDataList () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'

          }).then( ({data}) => {
            console.log("成功获取到菜单数据:"+data.data)
            this.menus=data.data;

          })
        }
      },
        // 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
      created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
        this.getDataList();
      }
    }
    </script>

我们的商品系统下的分类维护中成功显示出三级分类数据
在这里插入图片描述

5:删除-页面效果

我们先来编写菜单删除功能,哪些菜单可以被删除呢?那就是没有子菜单,并且没有被别的地方引用的菜单,操作如下
第一步:我们先来展示前端界面的删除效果,我们去eliment中找到Tree树形控件下的自定义节点内容,把它的代码引入,如下代码演示
在这里插入图片描述

<template>
<!--  使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据-->
  <!--label	指定节点标签为节点对象的某个属性值,,children	指定子树为节点对象的某个属性值,,,data	展示数据-->
  <el-tree
    :data="menus"
    show-checkbox
    node-key="id"
    :props="defaultProps"
    default-expand-all
    :expand-on-click-node="false">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{
  { node.label }}</span>
        <span>
          <el-button
            type="text"
            size="mini"
            @click="() => append(data)">
            Append
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => remove(node, data)">
            Delete
          </el-button>
        </span>
      </span>
  </el-tree>

</template>

<script>
    export default {
        // import引入的组件需要注入到对象中才能使用",
      components: {},
      data () {
            // 这里存放数据",
        return {
            menus: [],
            defaultProps: {
              children: 'children',
              label: 'name'
            }
        }
       },
        // 监听属性 类似于data概念",
      computed: {},
        // 监控data中的数据变化",
      watch: {},
        // 方法集合",
      methods: {
        append(data) {
        },
        remove(node, data) {

        },
        // 获取数据列表
        getDataList () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'

          }).then( ({data}) => {
            console.log("成功获取到菜单数据:"+data.data)
            this.menus=data.data;

          })
        }
      },
        // 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
      created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
        this.getDataList();
      },
    }
    </script>

就会变成如下效果
在这里插入图片描述
第二步:只有我们这个菜单是一级菜单或者是二级菜单的时候才显示append按钮(三级分类不可以追加元素);无论是一级分类还是二级分类,只要我们没子节点就可以删除;所以我们进行修改按钮,在合适的时机显示出来,添加如下v-if语句,v-if里面的判断值怎么得出呢?
我们要进行检查界面,观察点击按钮后,在控制台上打印值的变化,如下
在这里插入图片描述

 <el-button
            type="text"
            size="mini"
            @click="() => append(data)"
            v-if="data.catLevel<=2"
          >
            Append
          </el-button>
          <el-button
            type=&#
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值