当前位置: 首页 > news >正文

vue3 电商类网站实现规格的选择

目前有一个这样的需求 类似淘宝 京东选择 

但是在人家大厂给的数据我不清除是什么样子的 

我这边后端给的数据 一开始是想把规格全部显示出来的 发现实现不了 后端的数据有限

因为必须选择一个颜色 才可以对应的第二个规格 才知道有没有库存

因为这个库存 是由两个规格决定的 这种的话 要想 做成京东或者淘宝那种 

无库存无法显示的效果是不行的 看一下我的后端给的数据

 

[{"id": "1384947912936914944","image": "","stock": 0,"supplyCode": "","sellerPrice": "8250","masterAttrName": "颜色","masterAttrValue": "紫绿色调00374","slaveAttrName": "参考身高","slaveAttrValue": "160cm"},{"id": "1384947912953692160","image": "","stock": 19,"supplyCode": "","sellerPrice": "8250","masterAttrName": "颜色","masterAttrValue": "紫绿色调00374","slaveAttrName": "参考身高","slaveAttrValue": "165cm"},{"id": "1384947912970469376","image": "","stock": 50,"supplyCode": "","sellerPrice": "8250","masterAttrName": "颜色","masterAttrValue": "红绿色调00364","slaveAttrName": "参考身高","slaveAttrValue": "160cm"},{"id": "1384947912987246592","image": "","stock": 100,"supplyCode": "","sellerPrice": "8250","masterAttrName": "颜色","masterAttrValue": "红绿色调00364","slaveAttrName": "参考身高","slaveAttrValue": "165cm"}
]

这里面的数据 stock 是 0 的话 我前端自己又加了一个数据 isDisable字段 为true 无法选择

需要把这个数据整体更换成 这样的就好了

[{"value": "紫绿色调00374","disabled": false,"heights": [{"value": "160cm","stock": 0,"disabled": true},{"value": "165cm","stock": 19,"disabled": false}]},{"value": "红绿色调00364","disabled": false,"heights": [{"value": "160cm","stock": 50,"disabled": false},{"value": "165cm","stock": 100,"disabled": false}]}
]

最终我们需要这样的数据来显示 就好了

我认为这样的数据 才是 最符合 的 很明显 后端给的数据 差距太大 说实话 

我一下子没有想起来怎么把上面的数据处理成下面这样

我也是搜了搜

使用 new Map  映射一下 最后在Array.from(new Map.values)  映射出来就好了

我直接上代码吧

      colorOptions: [],heightOptions: [],filterOptions: [],  中转 相当于选择了规格1 的经过 去筛选规格2 的显示selectedColor: null, //规格1选择的结果selectedHeight: null    //规格1选择的结果initOptions() {const colorMap = new Map();const heightMap = new Map();// 首先收集所有颜色和身高选项this.originalData.forEach(product => {// 处理颜色选项if (!colorMap.has(product.masterAttrValue)) {colorMap.set(product.masterAttrValue, {value: product.masterAttrValue,disabled: false, // 初始不禁用heights: new Map() // 存储身高和对应的库存});}const colorOption = colorMap.get(product.masterAttrValue);colorOption.heights.set(product.slaveAttrValue, product.stock);// 处理身高选项if (!heightMap.has(product.slaveAttrValue)) {heightMap.set(product.slaveAttrValue, {value: product.slaveAttrValue,disabled: product.stock === 0, // 身高选项的禁用状态基于库存colors: new Map() // 存储颜色和对应的库存});}const heightOption = heightMap.get(product.slaveAttrValue);heightOption.colors.set(product.masterAttrValue, product.stock);});// 转换颜色选项:只有当所有身高都缺货时才禁用颜色this.colorOptions = Array.from(colorMap.values()).map(color => {const hasStock = Array.from(color.heights.values()).some(stock => stock > 0);return {...color,disabled: !hasStock,heights: Array.from(color.heights.entries()).map(([height, stock]) => ({value: height,stock,disabled: stock === 0}))};});// 转换身高选项this.heightOptions = Array.from(heightMap.values()).map(height => ({...height,colors: Array.from(height.colors.entries()).map(([color, stock]) => ({value: color,stock,disabled: stock === 0}))}));console.log(this.colorOptions, 'this.colorOptions');console.log(this.heightOptions, 'this.colorOptions');},

上面的数据到下面 这个方法就够了

然后页面上显示我也拿出来

  <div class="cate-selected-box"><div class="cate-title"> {{ info.masterAttrName }}</div><ul class="cate-list"><li class="level1-item" v-for="color in colorOptions" :key="color.value" @click="selectColor(color)":class="{ 'disabled': color.disabled, 'selected': selectedColor === color.value }">{{ color.value }}<span v-if="color.disabled">(缺货)</span></li></ul><div class="cate-title"> {{ info.slaveAttrName }}</div><ul class="cate-list" v-if="filterOptions.length"><li class="level1-item" v-for="item in filterOptions" v-if="item.value != '-'" :key="item.value"@click.stop="selectHeight(item)":class="{ 'disabled': item.disabled, 'selected': selectedHeight === item.value }">{{ item.value }}<span v-if="item.disabled">(缺货)</span></li></ul><div class="selected-info" v-if="info.productSpecials && info.productSpecials.length > 1"><div class="item"><div class="label">已选择:</div><!-- &&  --><div class="value"v-if="(info.slaveAttrValues && info.slaveAttrValues.length) && (info.masterAttrValues && info.masterAttrValues.length)"><div v-if="selectedColor && selectedHeight">{{ selectedColor }} - {{ selectedHeight }}</div></div><div class="value"v-if="(!info.slaveAttrValues) && (info.masterAttrValues && info.masterAttrValues.length)"><div v-if="selectedColor">{{ selectedColor }}</div></div></div></div></div>
li {list-style: none;padding: 0;margin: 0;
}ul {padding: 0;margin: 0;
}.cate-selected-box {.cate-title {font-weight: 700;margin: 10px 0;}.selected-info {margin: 15px;margin-top: 25px;.item {display: flex;align-items: center;.label {color: 858a99;}.value {color: #6034b9;margin-left: 10px;}}}.cate-list {cursor: pointer;display: flex;flex-wrap: wrap;align-items: center;.level1-item {padding: 10px 20px;border: 1px solid #f7f8f9;border-radius: 5px;transition: all 0.3s;margin: 6px;}.level1-item:hover {border: 1px solid #6034b9;}.level1-item:nth-child(n+2) {// margin-left: 10px;// margin: 10px;}}}.disabled {color: #ccc;cursor: not-allowed;
}.selected {background-color: #6034b9;color: white;border-color: #6034b9;
}

这一部分的样式我也显示出来了

大家如果把这个放到vue 文件中 是直接能够显示效果的

这里面的难点其实是这个 new Map 的使用 我也使用的好少 Es6 的方法如果说不使用 这个 其实 也能够想办法 把这个处理好 但是方法不太好想

这些都是经验吗 每次记一点 下次遇到了就能有想法了

学习前端就是这样 哪怕你死记硬背 有时候 也有用 就会知道什么方法处理什么问题

相关文章:

  • leetcode:461. 汉明距离(python3解法,数学相关算法题)
  • simuilink和ROS2数据联通,Run后一直卡在Initializting
  • 基于微信小程序和云开发的企业绿色融资平台的设计与实现
  • OpenCV CUDA模块设备层-----在GPU上计算两个uchar1类型像素值的反正切(arctangent)比值函数atan2()
  • 用Java将PDF转换成GIF
  • 从Excel到知识图谱再到数据分析:数据驱动智能体构建指南
  • 软件功能测试的测试标准
  • 优化数据库查询
  • 如何在Windows上安装.NET Framework 详细教程分享
  • react中使用antd的form表单去受控switch时初始值没有正确显示
  • Java面试题024:一文深入了解微服务消息队列RocketMQ
  • 泛微OAe9-后端二开常见数据库操作
  • 【JeecgBoot AIGC】AI工作流配置与流程节点全解析
  • Flink On Yarn HA 重启次数
  • PHP 生成当月日期
  • 软件项目管理(第4版)部分课后题答案
  • JS红宝书笔记 - 8.1 理解对象
  • ARINC653分区调度算法的研究与改进
  • 若依配置knife4j
  • vue 实现dot-dropdown
  • 山西太原网站制作/seo建站的步骤
  • 外贸建站哪家强外贸网站怎么做/网站买卖交易平台
  • 建网站要花费多少钱/互联网营销的特点
  • 个人专属logo设计/搜狗搜索引擎优化
  • sofish wordpress主题/郑州官网网站优化公司
  • 邢台163/郑州专业seo推荐