场景和上一篇一样,只是返回数据不同的处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<div v-for="(item, i) in attributes" :key="i" class="g-g-list">
<span class="g-l-t ">{{ item.groupName }}:</span>
<div class="span">
<!-- v-show="child.status == 2" -->
<span v-for="(child, j) in item.items" :key="j" class="c-btn" :class="
child.isCheck == 1 ? 'active'
:child.isCheck == 2 ? 'is-check':''" @click.stop="guiGChange(child, i, j)">{{ child.attrName }}</span>
</div>
</div>
</div>
<style>
.g-g-list {
font-size: 14px;
color: #871811;
}
.g-l-t {
margin-right: 8px;
}
.span {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.c-btn {
width: 64px;
height: 25px;
line-height: 23px;
border: 1px solid #CCCCCC;
margin: 0 8px 0 0;
font-size: 12px;
border-radius: 8px;
text-align: center;
cursor: pointer;
}
.c-btn.active {
border: none;
background: linear-gradient(360deg, #FFA750 0%, #FF7700 100%);
color: #fff;
}
/* 不能选中 */
.c-btn.is-check {
color: #fff;
background-color: #000;
}
</style>
<script>
const { createApp } = Vue
createApp({
data() {
return {
attrIds: [4609, 4601],
attrNames: ["25g", "番茄味"],
goodsAttrInfoDefCur: [], // 展示的规格默认数据
// 展示的规格选择
attributes: [
{
groupName: "零食(重量)",
items: [
{
attrId: 4608,
attrName: "50g",
skuList: [21433]
},
{
attrId: 4609,
attrName: "25g",
skuList: [21434, 21435]
},
]
},
{
groupName: "口味",
items: [
{
attrId: 4600,
attrName: "牛肉味",
skuList: [21433]
},
{
attrId: 4601,
attrName: "番茄味",
skuList: [21434]
},
{
attrId: 4601,
attrName: "黄瓜味",
skuList: [21435]
},
]
},
]
}
},
mounted() {
this.attrIds.forEach((e, i) => {
this.goodsAttrInfoDefCur.push(
{
attrId: e,
attrName:this.attrNames[i]
}
)
})
for (let i = 0; i < this.goodsAttrInfoDefCur.length; i++) {
const e = this.goodsAttrInfoDefCur[i]
for (let j = 0; j < this.attributes[i].items.length; j++) {
const e2 = this.attributes[i].items[j]
e2['isCheck'] = 0
if (e.attrId === e2.attrId) {
e2['isCheck'] = 1
this.guiGChange(e2, i, j)
}
}
}
},
methods: {
// 规格
guiGChange(child, attrI, childJ) {
// gInfoData.attributes[attrI].items.forEach(e => {
// e.isCheck = 0
// })
if (this.attributes[attrI].index > -1 && this.attributes[attrI].index === childJ) {
this.attributes[attrI].index = -1
this.attributes[attrI].attrId = -1
child.isCheck = 0
} else {
this.attributes[attrI].index = childJ
this.attributes[attrI].attrId = child.attrId
child.isCheck = 1
}
/**
* 判断选中当前的某一个行的规格的时候,剩下的规格按钮是否能被选中
* 选中的按钮不一定是按顺序选择的可能是 从下往上
*/
// 循环当前选中的数据
// console.log(this.attributes)
// const attrArr = this.attributes.slice()
for (let i = 0; i < this.attributes.length; i++) {
const e = this.attributes[i]
// if (e.index > -1) continue
let arr = []
for (let j = 0; j < this.attributes.length; j++) {
if (i === j) continue
const e2 = this.attributes[j]
if (e2.index > -1) {
const skuId = e2.items[e2.index].skuList
if (!arr.length) {
// 拿到当前的skuId
skuId.forEach(e => {
arr.push(e)
})
} else {
// 选中两种规格的时候 取出交集用于第三个规格的判断
if (skuId.length) {
// 取出剩余交集 跟 剩余行比较
arr = arr.filter((v) => {
return skuId.indexOf(v) > -1
})
}
}
}
}
// console.log(arr)
// 循环展示数据 当前行数 未选中的按钮 是否可以点击的处理
for (let x = 0; x < this.attributes.length; x++) {
const xG = this.attributes[x]
// 当前i行的判断
if (i === x) {
// 循环当前i行的所有skuid
for (let y = 0; y < xG.items.length; y++) {
// console.log(e.index)
const yG = xG.items[y]
// 当前选中的不算
if (y === e.index) continue
// 当前i行 下 未选中按钮 所包含的某一个的skuId
// 进行判断是否可以选中
let arrSkuId = yG.skuList.slice()
if (!arr.length) {
// 同行可以选中的
yG['isCheck'] = 0 // 是否可选
} else {
// 剩余行数的交集 进行交集的判断
arrSkuId = yG.skuList.filter((v) => {
return arr.indexOf(v) > -1
})
// console.log(yG.skuList);
yG['isCheck'] = arrSkuId.length ? 0 : 2 // 是否可选
}
// console.log(arrSkuId)
}
}
}
}
// console.log(gInfoData.attributes)
}
},
}).mount('#app')
</script>
</body>
</html>