后台管理系统: 商品管理

 商品管理之三级联动静态组件

先做俩个卡片组件,分开距离 

三级联动很多地方都用到了它,我们可以封装成一个组件

注册为一个全局组件

 

<div><el-form :inline="true" class="demo-form-inline"><el-form-item label="一级分类"><el-select  placeholder="请选择" value=""><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item><el-form-item label="二级分类"><el-select  placeholder="请选择" value=""><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item><el-form-item label="三级分类"><el-select  placeholder="请选择" value=""><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item>
</el-form></div>

商品管理之三级联动动态组件

书写相对于的api

  拿到数据,然后渲染到页面上

 一级分类完成

我们需要在一级联动数据发生改变的时候,把id传给二级联动。这里有一个注意点,就是这个是在组件中,@change这个其实就是自定义事件 

绑定事件,但是报错了

 接口测试没有问题,后面查询出来是接口的请求写错了

 

三级联动完成

一级分类数据发送变化的时候,二级,三级分类数据要变化。首先要清除原有的值,同时我们需要在子组件中给父组件传递参数

<template><div><!-- inline:代表的是行内表单,代表一行可以放置多个表单元素 --><el-form :inline="true" class="demo-form-inline" :model="cForm"><el-form-item label="一级分类"><el-selectplaceholder="请选择"v-model="cForm.category1Id"@change="handler1":disabled="show"><el-option:label="c1.name":value="c1.id"v-for="(c1, index) in list1":key="c1.id"></el-option></el-select></el-form-item><el-form-item label="二级分类"><el-selectplaceholder="请选择"v-model="cForm.category2Id"@change="handler2":disabled="show"><el-option:label="c2.name":value="c2.id"v-for="(c2, index) in list2":key="c2.id"></el-option></el-select></el-form-item><el-form-item label="三级分类"><el-selectplaceholder="请选择"v-model="cForm.category3Id"@change="handler3":disabled="show"><el-option:label="c3.name":value="c3.id"v-for="(c3, index) in list3":key="c3.id"></el-option></el-select></el-form-item></el-form></div>
</template><script>
export default {name: "CategorySelect",props: ["show"],data() {return {//一级分类的数据list1: [],//二级分类的数据list2: [],//三级分类的数据list3: [],//收集相应的一级二级三级分类的idcForm: {category1Id: "",category2Id: "",category3Id: "",},};},//组件挂载完毕:向服务器发请求,获取相应的一级分类的数据mounted() {//获取一级分类的数据的方法this.getCategory1List();},methods: {//获取一级分类数据的方法async getCategory1List() {//获取一级分类的请求:不需要携带参数let result = await this.$Api.attr.reqCategory1List();if (result.code == 200) {this.list1 = result.data;}},//一级分类的select事件回调(当一级分类的option发生变化的时候获取相应二级分类的数据)async handler1() {//清除数据this.list2 = [];this.list3 = [];this.cForm.category2Id = "";this.cForm.category3Id = "";//解构出一级分类的idconst { category1Id } = this.cForm;this.$emit("getCategoryId", { categoryId: category1Id, level: 1 });//通过一级分类的id,获取二级分类的数据let result = await this.$Api.attr.reqCategory2List(category1Id);if (result.code == 200) {this.list2 = result.data;}},//二级分类的select事件回调(当二级分类的option发生变化的时候获取相应三级分类的数据)async handler2() {//清除数据this.list3 = [];this.cForm.category3Id = "";//结构出数据const { category2Id } = this.cForm;this.$emit("getCategoryId", { categoryId: category2Id, level: 2 });let result = await this.$Api.attr.reqCategory3List(category2Id);if (result.code == 200) {this.list3 = result.data;}},//三级分类的事件回调handler3() {//获取三级分类的idconst { category3Id } = this.cForm;this.$emit("getCategoryId", { categoryId: category3Id, level: 3 });},},
};
</script><style scoped>
</style>

 父组件来接收数据

平台属性管理动态展示属性

就是三级联动数据确定那一刻,获取平台属性的内容

先写接口 

拿到数据 

动态渲染 

平台属性之添加属性与修改属性静态完成

通过一个v-show来控制这个显示和隐藏

这里有一个细节,那就是没有选一二三级。这个按钮就不能使用。这里我们用 :disabled="!category3Id" 如果有category3Id就是相当于可以使用

我们还需要写添加属性修改属性的结构

  <div v-show="!isShowTable"><el-form :inline="true" ref="form" label-width="80px" ><el-form-item label="属性名"><el-input placeholder="请输入属性名"></el-input></el-form-item></el-form><el-button type="primary" icon="el-icon-plus">添加属性值</el-button><el-button @click="isShowTable = true">取消</el-button><el-table style="width: 100%; margin: 20px 0px" border ><el-table-column align="center" type="index" label="序号" width="80"> </el-table-column><el-table-column width="width" prop="prop" label="属性值名称"></el-table-column><el-table-column width="width" prop="prop" label="操作"></el-table-column></el-table><el-button type="primary">保存</el-button><el-button @click="isShowTable = true">取消</el-button></div></el-card></div>

收集属性名和属性值操作

这里要说一下什么是属性和属性值

这块写属性名称     属性列表

属性:颜色

属性值:粉色,红色等等

调用这个接口

 携带参数有讲究的

"attrName": "string","attrValueList": [{"attrId": 0,"id": 0,"valueName": "string"}],"categoryId": 0,"categoryLevel": 0,"id": 0

 注意:别在data当中收集三级分类的id

因为对象存储数据是无序存储

就是你不能确定对象中的属性谁先谁后,因此这个this.category3Id就是undefined

 通过这种方式就能获取到表单的属性 

现在我们获取到了属性名,但是没有获取到属性值

 async getAttrList() {//获取分类的IDconst { category1Id, category2Id, category3Id } = this;//获取属性列表的数据let result = await this.$Api.attr.reqAttrList(category1Id,category2Id,category3Id);if (result.code == 200) {this.attrList = result.data;}}, addAttrValue() {//向属性值的数组里面添加元素//attrId:是你相应的属性的id,目前而言我们是添加属性的操作,还没有相应的属性的id,目前而言带给服务器的id为undefined//valueName:相应的属性值的名称this.attrInfo.attrValueList.push({attrId: this.attrInfo.id, //对于修改某一个属性的时候,可以在已有的属性值基础之上新增新的属性值(新增属性值的时候,需要把已有的属性的id带上)valueName: "",flag: true,});}

解决返回按钮数据回显问题

就是在每次按钮点击之前,把之前的数据清空。

同时我们这里可以点击添加属性按钮,收集到3id

addAttr() {//切换table显示与隐藏this.isShowTable = false;//清除数据//收集三级分类的idthis.attrInfo = {attrName: "", //属性名attrValueList: [//属性值,因为属性值可以有多个因此用数组,每一个属性值都是一个对象需要attrId,valueName],categoryId: this.category3Id, //三级分类的idcategoryLevel: 3, //因为服务器也需要区分几级id};},

修改属性操作

这个row就是这一行的属性值

 这里有一个bug,就是我们点击取消按钮的时候他也会变化。这里我们不能使用浅拷贝,由于数据结构当中存在对象里面套数组,数组里面有套对象,因此需要使用深拷贝解决这类问题

这里可以使用插件loadsh进行深拷贝,这就不能实现值不会随的v-model的修改,而修改了

查看模式与修改模式切换

当我们点击添加属性值按钮的时候就应该把属性的id传进去

对于修改某一个属性的时候,可以在已有的属性值基础之上新增新的属性值(新增属性值的时候,需要把已有的属性的id带上)

input跟span来回进行切换

参看模式:显示span

编辑模式:显示input

注意:通过flag标记进行切换参看模式与编辑模式,但是需要注意的时候,一个属性flag是没有办法控制全部属性的切换

解决方案就是在每个元素添加的时候给他添加一个属性flag

flag属性:给每一个属性值添加一个标记flag,用户切换查看模式与编辑模式,好处,每一个属性值可以控制自己的模式切换

当前flag属性,响应式数据(数据变化视图跟着变化) 

然后通过v-if来控制 当失去焦点和回车的时候,我们需要进行模式的切换 

查看模式与编辑模式注意事项

1.如果属性值为空不能作为新的属性值,需要给用户提示,让他输入一个其他的属性值

2.新增的属性值不能与已有的属性值重复

row最新新增的属性值【数组的最后一项元素】 而item是指得这个数组的每一项

修改查看模式和编辑模式的切换

就是我们切换到编辑模式上,发现flag是没有的,因为它是后面添加上的,并不是响应式数据

可以通过这种方式,但是视图并不会跟着变化(对象中后追加的属性,Vue默认不做响应式处理) 

这里我们需要使用$set

第一个参数:对象  第二个参数:添加新的响应式属性  第三参数:新的属性的属性值

表单元素自动对焦实现

点击span的时候,获取到input的节点,然后自动对焦

这里我们给span绑定一个事件 同时给input 用ref获取到它的节点,但是这个input并不是一个而是多个。因此我们可以用索引值当做它的标记 用于区分它是第几个信息

获取input节点,实现自动聚焦

        需要注意:点击span的时候,切换为input变为编辑模式,但是需要注意,对于浏览器而言,页面重绘与重拍耗时间的

       点击span的时候,重绘重拍一个input它是需要耗费事件,因此我们不可能一点击span立马获取到input

       $nextTick,当节点渲染完毕了,会执行一次

除了切换span要获取聚焦外,点击添加属性值按钮也应该让获取到数组的最后一项聚焦

删除属性值的操作

这里我们需要用到这个组件

 复制到代码中,结构大概是这样的

这里使用模板字符串的方式,告诉用户删除的是那个 confirm是气泡确定框确定事件

但是我们会发现调用这个办法是没有效果的,因为我们这个项目的版本是老版本很旧

 所以用@onConfirm

保存操作

用这个接口

 这里提交给服务器的参数,有俩个讲究

整理参数:1,如果用户添加很多属性值,且属性值为空的不应该提交给服务器

2.提交给服务器数据当中不应该出现flag字段

用filter这个方法实现那flag这个属性过滤掉 

按钮与三级联动的可操作性 

isShowTable给子传过去 

子接收show属性 

然后通过这个属性来控制 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/90551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1200*A. Flipping Game(前缀和)

解析&#xff1a; 100数据量&#xff0c;两层遍历每个区间&#xff0c;然后前缀和计算1的个数&#xff0c;维护最大值即可。 #include<bits/stdc.h> using namespace std; #define int long long const int N110; int n,a[N],res,sum[N]; signed main(){scanf("%ll…

目标检测:FROD: Robust Object Detection for Free

论文作者&#xff1a;Muhammad,Awais,Weiming,Zhuang,Lingjuan,Lyu,Sung-Ho,Bae 作者单位&#xff1a;Sony AI; Kyung-Hee University 论文链接&#xff1a;http://arxiv.org/abs/2308.01888v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;目标检测 2&#xff09;…

3.6+铁死亡+WGCNA+机器学习

今天给同学们分享一篇3.6铁死亡WGCNA机器学习的生信文章“Identification of ferroptosis related biomarkers and immune infiltration in Parkinsons disease by integrated bioinformatic analysis”&#xff0c;这篇文章于2023年3月14日发表在BMC Med Genomics期刊上&#…

队列的使用以及模拟实现(C++版本)

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;强烈推荐优质专栏: &#x1f354;&#x1f35f;&#x1f32f;C的世界(持续更新中) &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;…

C运算符和控制语句

几乎每一个程序都需要进行运算&#xff0c;对数据进行加工处理&#xff0c;否则程序就没有意义了。要进行运算&#xff0c;就需规定可以使用的运算符。 C语言的运算符范围很宽&#xff0c;把除了控制语句和输人输出以外的几乎所有的基本操作都作为运算符处理。 运算符分类1 除…

likeadmin和fastapi的bug

以下内容写于2023年8月11日 bug 1 请求体 - 多个参数 - FastAPI (tiangolo.com)中“请求体中的单一值”处&#xff0c;选python3.6&#xff0c;接口示例代码是 from typing import Unionfrom fastapi import Body, FastAPI from pydantic import BaseModel from typing_exte…

Spring Boot中配置文件介绍及其使用教程

目录 一、配置文件介绍 二、配置简单数据 三、配置对象数据 四、配置集合数据 五、读取配置文件数据 六、占位符的使用 一、配置文件介绍 SpringBoot项目中&#xff0c;大部分配置都有默认值&#xff0c;但如果想替换默认配置的话&#xff0c;就可以使用application.prop…

从零手搓一个【消息队列】项目设计、需求分析、模块划分、目录结构

文章目录 一、需求分析1, 项目简介2, BrokerServer 核心概念3, BrokerServer 提供的核心 API4, 交换机类型5, 持久化存储6, 网络通信7, TCP 连接的复用8, 需求分析小结 二、模块划分三、目录结构 提示&#xff1a;是正在努力进步的小菜鸟一只&#xff0c;如有大佬发现文章欠佳之…

阿里云效自动构建python自动测试脚本

之前一直用的是jenkins自动构建自动化脚本&#xff0c;因为现在的公司统一在阿里云效的流水线上做代码的管理&#xff0c;构建&#xff0c;要求自动化测试也在上面自动构建&#xff0c;故而学习了一下。为自己做一个记录&#xff0c;也给有需要的朋友做一个参考。 1. 新建流水…

设计模式4、建造者模式 Builder

解释说明&#xff1a;将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示 UML 结构图&#xff1a; 抽象建造者&#xff08;Builder&#xff09;&#xff1a;这个接口规定要实现复杂对象的那些部分的创建&#xff0c;并不设计具体部件对象的创…

在MySQL中使用VARCHAR字段进行日期筛选

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

ROS2 从头开始​​:第6部分 - ROS2 中的 DDS,用于可靠的机器人通信

一、说明 在这篇文章中,我们将重点关注 ROS 2的通信栈DDS,其中这是介于管理节点通信与控制节点通信环节,是上位机决策体系与下位机的控制体系实现指令-执行-反馈的关键实现机制。 二、ROS工程的概念框架 现代机器人系统非常复杂,因为需要集成各种类型的传感器、执行器和其…

No148.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

MySQL到TiDB:Hive Metastore横向扩展之路

作者&#xff1a;vivo 互联网大数据团队 - Wang Zhiwen 本文介绍了vivo在大数据元数据服务横向扩展道路上的探索历程&#xff0c;由实际面临的问题出发&#xff0c;对当前主流的横向扩展方案进行了调研及对比测试&#xff0c;通过多方面对比数据择优选择TiDB方案。其次分享了整…

查看react内置webpack版本的方法

yarn list --pattern webpack npm ls --pattern webpack

Python3操作SQLite3创建表主键自增长|CRUD基本操作

Win11查看安装的Python路径及安装的库 Python PEP8 代码规范常见问题及解决方案 Python3操作MySQL8.XX创建表|CRUD基本操作 Python3操作SQLite3创建表主键自增长|CRUD基本操作 anaconda3最新版安装|使用详情|Error: Please select a valid Python interpreter Python函数绘…

Docker版部署RocketMQ开启ACL验证

一、拉取镜像 docker pull apache/rocketmq:latest 二、准备挂载目录 mkdir /usr/local/rocketmq/data mkdir /usr/local/rocketmq/conf 三、运行 docker run \ -d \ -p 9876:9876 \ -v /usr/local/rocketmq/data/logs:/home/rocketmq/logs \ -v /usr/local/rocketmq/data…

十五.镜头知识之景深(Depth of Field)

十五.镜头知识之景深(Depth of Field) 文章目录 十五.镜头知识之景深(Depth of Field)15.1 概述15.2 景深(depth of field)定义15.3 景深原理15.3.1 弥散圆(circle of confusion) 15.4 景深总结 15.1 概述 先看两个例子&#xff0c;拍摄花、昆虫等照片时&#xff0c;背景拍的比…

【C++】vector的介绍 | 常见接口的使用

目录 vector的介绍 常见接口 构造函数 尾插push_back() vector的遍历 1.用方括号下标 遍历&#xff1a; 2.调用at()来访问&#xff1a; 3.用迭代器遍历&#xff1a; 4.范围for遍历&#xff1a; vector空间 vector增删查改 覆盖assign() 查找find() 插入insert() …

【加载数据--自定义自己的Dataset类】

【加载数据自定义自己的Dataset类】 1 加载数据2 数据转换3 自定义Dataset类4 划分训练集和测试集5 提取一批次数据并绘制样例图 假设有四种天气图片数据全部存放与一个文件夹中&#xff0c;如下图所示&#xff1a; ├─dataset2 │ cloudy1.jpg │ cloudy10.jpg │ …