先看看数据效果
也就是选择Size 下面的Color 要跟着判断是否缺货;相反选择Color也要判断是否有对应的尺码
别想复杂了,也别担心,当你敲完之后,会发现其实很简单,就是拿当前选择的去跟你的字典对比,存在就是有库存,不存在就没库存
先看看后端给的数据结构吧
//这个 是默认返回的sku数据 Size模块下XL 【建议80-100斤】 选中;
//Color classification下 Blue [ Fleece-lined Tops ]选中;
let defaultSku=[
{
"paramName": "Size",
"sort": null,
"isCommon": null,
"refSpecId": null,
"paramValue": "XL 【建议80-100斤】"
},
{
"paramName": "Color classification",
"sort": null,
"isCommon": null,
"refSpecId": null,
"paramValue": "Blue [ Fleece-lined Tops ]"
}
];
//这个就是 当前有哪些类别,类别下面有哪些分类;也就是前面图片上的Size和Color classification模块和模块下面对应的选项;
let skuList=[
{
"paramName": "Size",
"sort": 1,
"isCommon": null,
"refSpecId": null,
"paramNameValues": [
"XL 【建议80-100斤】",
"2XL 【建议100-115斤】",
],
"paramNameValuesActivity": null
},
{
"paramName": "Color classification",
"sort": 2,
"isCommon": null,
"refSpecId": null,
"paramNameValues": [
"Blue [ Fleece-lined Tops ]",
"Red [ Fleece-lined Tops ]",
"Purple [ Fleece-lined Tops ]",
],
"paramNameValuesActivity": null
}
]
//这里就是后端返回的sku数据 也就是一个尺码对应一个颜色的组合
let skuGoodsList=[
{
"specValue": [
{
"paramName": "Size",
"paramValue": "XL 【建议80-100斤】"
},
{
"paramName": "Color classification",
"paramValue": "Blue [ Fleece-lined Tops ]"
}
],
"goodsStock": 10,//这里就加一个库存数据 需要啥的 让后端给你返回 比如图片 价格
},
{
"specValue": [
{
"paramName": "Size",
"paramValue": "XL 【建议80-100斤】"
},
{
"paramName": "Color classification",
"paramValue": "Red [ Fleece-lined Tops ]"
}
],
"goodsStock": 10,//这里就加一个库存数据 需要啥的 让后端给你返回 比如图片 价格
}
]
当我们拿到这些数据的时候,我们先处理skuGoodsList
我也是网上copy的 先把这个方法存起来
// 计算子集的方法
export function bwPowerSet(originalSet) {
const subSets = []
const numberOfCombinations = 2 ** originalSet.length
for (let combinationIndex = 0; combinationIndex < numberOfCombinations; combinationIndex += 1) {
const subSet = []
for (let setElementIndex = 0; setElementIndex < originalSet.length; setElementIndex += 1) {
if (combinationIndex & (1 << setElementIndex)) {
subSet.push(originalSet[setElementIndex])
}
}
subSets.push(subSet)
}
return subSets
}
//然后我们生成一个字典对象,到时候点击的时候直接去字典对比 就好了
//也就是拿到数据之后 调用下
let pathMapList=getPathMap(skuGoodsList)
// 生成有效路径字典对象
getPathMap(goods){
let pathMap=this.pathMap
// 过滤掉 库存不满足的数据
const effectiveSkus=goods.filter(sku=>sku.goodsStock>0)
// 子集算法
effectiveSkus.forEach(item=>{
// 匹配paramName组成的数组
const selectedValArr=item.specValue.map(val=>val.paramValue)
// 使用算法获取子集
const valueArrPowerSet=bwPowerSet(selectedValArr)
// 得到的子集最终生成字典对象
valueArrPowerSet.forEach(v=>{
const key=v.join('-')
// 如果已经存在 直接添加值 如果不存在就直接存
pathMap[key]={
goodsStock:item.goodsStock,
}
})
})
return pathMap
}
//通过上面步骤 你就能得到一个字典数据
pathMapList 的数据结构就是这样
pathMapList={
"XL 【建议80-100斤】-Red [ Fleece-lined Tops ]":{goodsStock:10},
"XL 【建议80-100斤】-Blue [ Fleece-lined Tops ]":{goodsStock:10}
....
}
到这里我们就处理好了数据的问题
然后我们做样式处理 也就是点击选中和取消选中
- 先处理下skuList的数据结构,因为我们如果要选中的话,添加一个selected字段来控制是最好的
skuList.forEach(item=>{
item.paramNameValues=
item.paramNameValues.map(key=>({name:key,picture:null}))
})
//这样 上面的 paramNameValues 就变成了对象的形式
//然后我们把数据渲染之后,触发点击事件
// 点击选中和取消选中
clickSpecFn(e,val){//e 就是整个paramNameValues val 就是当前点击的paramNameValues下面的某一个
//如果当前存在缺货 是不能点击的
if(val.disabled) return
//如果是选中状态 取消选中 这里应该能看懂吧
if(val.selected){
val.selected=false
}else{
e.paramNameValues.forEach(val=>val.selected=false)
val.selected=true
}
//选择之后 更新数据 去字典里面对比
this.updateDisabledStatus(skuList,pathMapList)
},
// 切换时更新状态 判断是否有库存 通过disabled 来显示样式
updateDisabledStatus(specs,pathMap){
specs.forEach(async (item,index)=>{
const selectedValues=await this.getSelectedValues(specs)
item.paramNameValues.forEach(val=>{
selectedValues[index]=val.name
const key=selectedValues.filter(v=>v).join('-')
if(pathMap[key]){
val.disabled=false
}else{
val.disabled=true
}
})
})
}
-
到这里其实都差不多了,然后给你的代码添加selected和disabled样式即可
-
可能有更好的方法,这个仅仅只是我学习来的,继续加油