需求(商城购物,规格的选择)
商品属性(多种):尺寸,颜色,款式
存在的组合方式是确定的:即就是所存在的库存并且大于0的sku
思路:点击的时候,记录当前点击的值,遍历sku,当前点击的sku中的每个元素,合并去重,还等于当前本身,则该元素里的子规格都是可点击的,子规格的其他就说不可点击,置灰。再次点击,拿到已经点击过的值。重复上述操作。
主要有三组数据:
- 所有的主规格(去重)数组对象 mainSKUList
- 所有的子规格(去重) 对象数组 childSKUList 根据key主规格id进行分类
- 所有的sku 数组对象 skuList
简单处理后端返回的数据
mainSKUList = [
{
id: 1,
name: '颜色'
},
{
id: 2,
name: '款式'
},
{
id: 3,
name: '尺寸'
}
]
childSKUList = {
1:[
{
childid: 11,
childsSpecName: '红',
checked: false,
disabled: false
},
{
childid: 12,
childsSpecName: '白',
checked: false,
disabled: false
}
],
2: [
{
childid: 21,
childsSpecName: '乞丐款',
checked: false,
disabled: false
},
{
childid: 22,
childsSpecName: '爆炸款',
checked: false,
disabled: false
}
],
3: [
{
childid: 31,
childsSpecName: 's',
checked: false,
disabled: false
},
{
childid: 32,
childsSpecName: 'm',
checked: false,
disabled: false
}
]
}
skuList = [['s', '红', '乞丐款'],['s', '红', '爆炸款'],['m', '红', '乞丐款'],['m', '红', '爆炸款'],['s', '白', '乞丐款'],['s', '白', '爆炸款']]
页面渲染
<div class="one-classfy" v-for="(item, index) in mainSKUList" :key="index">
<p class="title-name">{{item.name}}</p>
<button v-for="(el, i) in childSKUList[item.id]" :key="i" :class="el.checked ? 'selectActive' : ''" @click="checkSingleChildSpec(el, index, i)" :disabled="el.disabled">
{{el.childsSpecName}}
</button>
</div>
选择子规格
// 获取可以选择的项
getCanCheckSpec(checkedSpecArr) {
let couldCheckItems = []
this.skuList.map(item => {
let curr = [...item]
curr = Array.from(new Set(curr.concat(checkedSpecArr)))
if ([...curr].sort().join(',') === [...item].sort().join(',')) {
couldCheckItems = couldCheckItems.concat(item)
}
})
return Array.from(new Set(couldCheckItems))
},
// 获取所有选择了的子规格
getCheckedSpecList() {
let checkedChildSKUList = []
Object.keys(this.checkedChildSKUList).map(key => {
checkedChildSKUList.push(this.checkedChildSKUList[key])
})
return checkedChildSKUList
},
checkSingleChildSpec(childSpec, index, i) {
// 先把所有同级的子规格去选
let mainSKU = this.mainSKUList[index]
let cIndex = this.childSKUList[mainSKU.id].findIndex(
child => child.checked === true
)
if (cIndex > -1 && cIndex !== i) {
this.childSKUList[mainSKU.id][cIndex].checked = false
}
childSpec.checked = !childSpec.checked
// 将选中的子规格存入备用
this.checkedChildSKUList[mainSKU.mainSpecId] = childSpec.checked
? childSpec.childsSpecName
: undefined
// 查找已经选中的子规格
let checkedSpecBtns = this.getCheckedSpecList()
// 根据已经选中的子规格获取可以选中的其他子规格,不包含同规格下的可选状态
let allCanCheckSpecBtns = this.getCanCheckSpec(checkedSpecBtns)
// 每点击一次都去匹配是不是有sku,shopSkuVo为后端返回的所有sku
let skuEntry = this.shopSkuVo.find(
item =>
item.specNames
.split('/')
.sort()
.join(',') === checkedSpecs.sort().join(',')
)
// 获取用户所点击的skuId
if (skuEntry) {
let selectSku = this.shopSkuVo.filter(d => d.skuId === skuEntry.skuId)
}
}