先拿到skuList,这边后端返回的skuLis是这种格式
skuList = [
{
"skuId": 50,
"price": 1799.0,
"oriPrice": 1799.0,
"stocks": 99,
"skuName":
"8+128GB 黑 ",
"pic": null,
"properties":
"内存:8+128GB;机身颜色:黑"
},
{
"skuId": 52,
"price": 1399.0,
"oriPrice": 1959.0,
"stocks": 9,
"skuName": "8+256GB 黑 ",
"pic": null,
"properties":
"内存:8+256GB;机身颜色:白"
}
]
处理好数据 把每一个规格标签取出来
需要把数据处理成这样
{
内存:[128GB,256GB],
机身颜色:[黑色,白色]
}
遍历skuList,取出properties
实现代码
var obj ={}
skuList.forEach(ele=>{
ele.properties.split(';').forEach(el=>{
obj[el.split(':')[0]]=[]
})
})
skuList.forEach(ele=>{
ele.properties.split(';').forEach(el=>{
if(obj[el.split(':')[0]].indexOf(el.split(':')[1])!=-1) return
obj[el.split(':')[0]].push( el.split(':')[1])
})
})
使用v-for渲染处理好的数据
循环每个规格在渲染时做判断 所以要在判断的方法里通过当前要判断是否禁用的规格(假设当前循环到的这一个规格为i),用i去拼接其他类型的已选中的规格得出i的properties,通过i的properties在skyList找出相同的数据,从而筛选当前匹配的sku,最后通过库存属性返回布尔值
实现代码
isAbled(selectedobj, key, item, skuKeys, skuList) {
var properties = "";
for (var j = 0; j < skuKeys.length; j++) {
properties += skuKeys[j] + ":" + selectedobj[skuKeys[j]] + ";";
}
properties = properties.substring(0, properties.length - 1); //首先获取当前选中的规格
var find = true
var skuserchArr = properties.split(';') // 将当前选中的规格转为数组
var skuserchKey = key + ':' + item //当前循环到的这个规格标签
var newsku = skuserchArr.map(function(ele) { //看当前循环到的标签类型等不等于选中的 只需要取其他类型的规格标签
if (ele.split(':')[0] == key) {
return skuserchKey
} else {
return ele
}
})
newsku = newsku.join(";") //生成循环到的这一个规格和已经选中的其他类型的规格的组合
var targetSku = {}
skuList.forEach(function(ele) { //找到生成的规格属于skuList中的哪一条数据
if (newsku == ele.properties) {
targetSku = ele
}
})
if (targetSku.stocks == 0) {
find = false
}
//判断找到的这条数据的库存等不等于0,返回布尔值
return find;
}
}
最后只需要通过布尔值判断规格是否禁用就行了
最后成功实现效果 红色为选中的规格 灰色为禁用的规格
完整的实现代码:
<template>
<view class="content">
<!-- <image class="logo" src="/static/logo.png"></image> -->
<view class="text-area">
<button @click="selectSku">选择规格</button>
</view>
<view class="sku_select" v-if="isShow">
<view class="" v-for="(value,key) in skuGroup" :key="key" @tap="changeSku">
<view class="">
{{key}}
</view>
<view class="pup-sku-area">
<view :class="'sku_item '+(seleArr.indexOf(item)!=-1?'color':'')+' '+(isAbled(selectedobj, key, item, skuKeys, skuList)?'':'abled') " v-for="(item,index) in value"
:data-key="key" :data-value='item' :key="item" :data-abled="isAbled(selectedobj, key, item, skuKeys, skuList)">
{{item}}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
isShow: true,
skuList: [{
"skuId": 671,
"price": 1799.0,
"oriPrice": 1799.0,
"stocks": 99,
"skuName": "8+128GB 黑 ",
"pic": null,
"properties": "内存:8+128GB;机身颜色:黑"
},
{
"skuId": 671,
"price": 1799.0,
"oriPrice": 1799.0,
"stocks": 99,
"skuName": "8+128GB 白 ",
"pic": null,
"properties": "内存:8+128GB;机身颜色:白"
},
{
"skuId": 672,
"price": 1999.0,
"oriPrice": 1999.0,
"stocks": 0,
"skuName": "8+256GB 白 ",
"pic": null,
"properties": "内存:8+256GB;机身颜色:白"
},
{
"skuId": 672,
"price": 1999.0,
"oriPrice": 1999.0,
"stocks": 0,
"skuName": "8+256GB 黑 ",
"pic": null,
"properties": "内存:8+256GB;机身颜色:黑"
},
{
"skuId": 672,
"price": 1999.0,
"oriPrice": 1999.0,
"stocks": 99,
"skuName": "8+256GB 红 ",
"pic": null,
"properties": "内存:8+256GB;机身颜色:红"
},
{
"skuId": 671,
"price": 1799.0,
"oriPrice": 1799.0,
"stocks": 0,
"skuName": "8+128GB 红 ",
"pic": null,
"properties": "内存:8+128GB;机身颜色:红"
},
],
skuGroup:{},
selectedobj:{},
seleArr:[],
skuKeys:[]
}
},
onLoad() {
this.skuList.forEach(ele=>{
ele.properties.split(';').forEach(el=>{
this.skuGroup[el.split(':')[0]]=[]
this.selectedobj[el.split(':')[0]]=''
})
})
this.skuList.forEach(ele=>{
ele.properties.split(';').forEach(el=>{
if(this.skuGroup[el.split(':')[0]].indexOf(el.split(':')[1])!=-1) return
this.skuGroup[el.split(':')[0]].push( el.split(':')[1])
})
})
console.log(this.skuGroup);
},
methods: {
selectSku() {
this.isShow = true
},
changeSku(e){
let key =e.target.dataset.key
let value =e.target.dataset.value
let abled =e.target.dataset.abled
if(!abled)return
var seleArr=[]
var skuKeys=[]
// this.selectedobj[key]=value
this.$set(this.selectedobj,key,value)
if(this.seleArr.indexOf(value)!=-1){
this.$set(this.selectedobj,key,'')
this.seleArr[this.seleArr.indexOf(value)]=''
}else{
for(var i in this.selectedobj ){
seleArr.push(this.selectedobj[i])
skuKeys.push(i)
}
}
this.seleArr=seleArr
this.skuKeys=skuKeys
console.log(this.selectedobj,this.seleArr,this.skuKeys,abled);
},
isAbled(selectedobj, key, item, skuKeys, skuList) {
var properties = "";
for (var j = 0; j < skuKeys.length; j++) {
properties += skuKeys[j] + ":" + selectedobj[skuKeys[j]] + ";";
}
properties = properties.substring(0, properties.length - 1); //首先获取当前选中的规格
var find = true
var skuserchArr = properties.split(';') // 将当前选中的规格转为数组
var skuserchKey = key + ':' + item //当前循环到的这个规格标签
var newsku = skuserchArr.map(function(ele) { //看当前循环到的标签类型等不等于选中的 只需要取其他类型的规格标签
if (ele.split(':')[0] == key) {
return skuserchKey
} else {
return ele
}
})
newsku = newsku.join(";") //生成循环到的这一个规格和已经选中的其他类型的规格的组合
var targetSku = {}
skuList.forEach(function(ele) { //找到生成的规格属于skuList中的哪一条数据
if (newsku == ele.properties) {
targetSku = ele
}
})
if (targetSku.stocks == 0) {
find = false
}
//判断找到的这条数据的库存等不等于0,返回布尔值
return find;
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.sku_select {
width: 100%;
position: fixed;
height: 400px;
bottom: 0;
}
.pup-sku-area{
display: flex;
}
.sku_item{
margin: 15px;
border: 1px solid #ddd;
padding: 5px;
}
.color{
background-color: red;
color: white;
}
.abled{
background-color: gray;
color: white;
}
</style>