文章目录
- 一,48-商品服务-API-三级分类-查询-树形展示三级分类数据
- 1,创建商品服务命名空间
- 2,商品服务增加配置
- 3,网关增加商品服务的路由配置
- 4,前端树形展示
- 5,测试
- 二,49-商品服务-API-三级分类-删除-页面效果
- 1,支持编辑三级分类
- 2,体验优化
- 完整代码
- 高效干活:nacos快速启动
本节的主要内容是前后端联调,解决网关到商品服务的路由配置、前端的树形展示、已经前端的功能增加和体验优化。
一,48-商品服务-API-三级分类-查询-树形展示三级分类数据
1,创建商品服务命名空间
在nacos上创建product命名空间,所有商品服务相关的配置都放在这个空间。
把商品服务数据库相关的配置从本地迁移到nacos。
2,商品服务增加配置
商品服务增加bootstrap.yml配置文件,其中包含nacos配置中心信息:
- 配置中心地址
- 配置中心命名空间
- 服务名称
spring:
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: 709272d4-12a3-4657-b039-af32012c794f
application:
name: gulimall-product
3,网关增加商品服务的路由配置
网关配置路由。
- id: gulimall-product
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
这段配置是Spring Cloud Gateway的路由规则定义,它用于将特定的HTTP请求转发到微服务后端。下面是配置的详细解释:
-
id: gulimall-product
:
这是路由的唯一标识符,可以帮助你在配置中引用这个路由规则。 -
uri: lb://gulimall-product
:
这指定了当匹配路由规则时,请求应该被转发到哪个服务。这里的lb://
表示使用负载均衡方式调用服务。gulimall-product
是服务名,通常在服务发现机制(如Netflix Eureka、Consul等)中注册的服务实例会被查找。 -
predicates
:
这是一个谓词列表,用于定义哪些请求应该被此路由规则处理。这里的Path=/api/product/**
表示任何以/api/product/
开头的URL路径都会匹配这个规则。 -
filters
:
路由过滤器允许对请求和响应进行修改。这里的RewritePath=/api/(?<segment>.*),/$\{segment}
是一个路径重写过滤器,其作用是将原始请求路径中的/api/
部分移除,然后将剩余部分转发给目标服务。/(?<segment>.*?)
: 这个正则表达式捕获从/api/
开始直到下一个/
前的所有字符(包括多个层级的路径),并将这部分保存为名为segment
的组。,/$\{segment}
: 这个字符串模板告诉Spring Cloud Gateway将捕获的segment
值替换回URL中,但不包含/api/
这部分。
举个例子,如果客户端发送一个请求到http://localhost:8080/api/product/list
,根据上述配置,这个请求将会被重写为http://gulimall-product/list
(假设gulimall-product
服务监听在默认端口上),从而绕过/api/
前缀直接转发给gulimall-product
服务。
4,前端树形展示
为了将三级分类在前端以树形结构进行展示,需要对组件category.vue做几处调整。
- 将数组名改为menus,更容易读
- label改为name,是因为后台数据中分类名称字段名是那么
此外,请求接口获得分类数据后,为数组menus赋值。
完整代码
<template>
<el-tree
:data="menus"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
components: {},
props: {},
data () {
return {
menus: [],
defaultProps: {
children: 'children',
label: 'name',
},
}
},
methods: {
handleNodeClick (data) {
console.log(data)
},
// 获取分类数据
getDataList () {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then(({data}) => {
console.log(data)
this.dataListLoading = false
this.menus = data.data
})
}
},
created() {
this.getDataList() // 获取分类数据
}
}
</script>
<style scoped>
</style>
5,测试
在浏览器中访问,发现商品分类已经以树形结构进行展示了。
二,49-商品服务-API-三级分类-删除-页面效果
这一节的内容是优化前端界面,增加下列特性。
1,支持编辑三级分类
在每个三级分类后面增加两个按钮:
- append,每个分类增加子分类
- delete,删除当前分类
要实现这个效果,参考官网,在el-tree
标签下增加如下代码。
<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>
同时,脚本下增加两个相对应的函数。
保存代码,刷新浏览器界面,两个按钮就会出现分类后。
2,体验优化
①点击append和delete按钮时,不要收缩分类树
el-tree绑定属性即可::expand-on-click-node="false"
②一级和二级分类才能append子分类,三级分类不能append
使用v-if
结合分类数据的结构,满足条件才展示响应的按钮。
在Vue.js中,v-if
是一个条件渲染指令,它根据表达式的真假来判断是否应该渲染一段代码。当表达式的结果为真时,对应的元素或片段将被插入到DOM中;反之,如果结果为假,则对应的元素或片段将不会被渲染,也就是说,它们完全不会存在于最终的DOM树中。
现在分析一下代码段:
<el-button v-if="node.level<=2" size="mini" @click="() => append(data)">
Append
</el-button>
<el-button v-if="node.childNodes.length==0" type="text" size="mini" @click="() => remove(node, data)">
Delete
</el-button>
两个<el-button>
标签,每个都使用了v-if
指令:
-
①第一个按钮的
v-if
条件是node.level<= 2
。这意味着只有当node.level
属性的值小于等于2时,这个按钮才会被渲染。 -
②第二个按钮的
v-if
条件是node.childNodes.length == 0
。这意味着只有当节点没有子节点时,“Delete”按钮才会被渲染,只允许删除没有子节点的节点。
③增加复选框
el-tree增加show-checkbox属性,即可显示复选框。
④el-tree增加node-key
在Element UI的el-tree
组件中,node-key
属性用于指定树节点的唯一标识符。在树形结构的数据集中,每个节点通常都有一个唯一的ID或键,用来区分不同的节点。node-key
属性就是用来告诉el-tree
组件使用哪个字段作为节点的唯一标识。
作用:
①唯一标识:通过node-key
属性,你可以指定树节点数据模型中哪个字段的值作为节点的唯一标识符。这在处理复杂的树形数据结构时非常有用,因为每个节点的标识符需要是全局唯一的,以避免在操作节点(如展开、折叠、选择、删除等)时产生冲突。
②性能优化:使用node-key
可以提高el-tree
组件在大数据量下的性能,尤其是在节点频繁变动的情况下。这是因为当el-tree
内部需要查找或操作某个节点时,它可以快速定位到该节点,而无需遍历整个树。
③状态管理:在使用el-tree
时,组件可能会存储某些状态信息,比如哪些节点被选中或展开。node-key
属性的值可以帮助组件在更新状态时准确地追踪和识别每个节点。
完整代码
<template>
<el-tree node-key="catId" :data="menus" :props="defaultProps" :expand-on-click-node="false" show-checkbox>
<span class="custom-tree-node" slot-scope="{ node, data }" >
<span>{{ node.label }}</span>
<span>
<el-button v-if="node.level<=2" size="mini" @click="() => append(data)">
Append
</el-button>
<el-button v-if="node.childNodes.length==0" type="text" size="mini" @click="() => remove(node, data)">
Delete
</el-button>
</span>
</span>
</el-tree>
</template>
<script>
export default {
components: {},
props: {},
data() {
return {
menus: [],
defaultProps: {
children: "children",
label: "name",
},
};
},
methods: {
append(data){
console.log(data);
},
remove(node, data){
console.log(node, data);
},
// 获取分类数据
getDataList() {
this.dataListLoading = true;
this.$http({
url: this.$http.adornUrl("/product/category/list/tree"),
method: "get",
}).then(({ data }) => {
console.log(data);
this.dataListLoading = false;
this.menus = data.data;
});
},
},
created() {
this.getDataList(); // 获取分类数据
},
};
</script>
<style scoped>
</style>
高效干活:nacos快速启动
windows上nacos的本地启动比较麻烦,每次要打开cmd,切换到对应目录,执行一个不容易记住命令,效率很低。
要解决这个问题也很简单,写一个bat脚本,配置到环境变量中,以后只要输入一个简单的命令就可以启动nacos了。
@echo off
setlocal enabledelayedexpansion
set NAOS_HOME=D:\sofeware\nacos-server-2.1.2\nacos
cd /d "!NAOS_HOME!\bin"
call startup.cmd -m standalone
endlocal
将这个脚本所在的目录配置到环境变量。
之后,只要在cmd输入下面的命令就可以启动nacos了。