vue商城:商品规格数据处理
后台接口返回的数据结构在vue中,使用forEach()来处理成自己想要的数据data() {return {show:false,//商品规格弹框price:'',//商品默认价格stock_num:'',//商品默认总库存if_sku:true,//判断该商品是否有规格sku:[],//商品规格select_id:[],//加入购物车/购买...
·
后台接口返回的数据结构
在vue中,使用forEach()来处理成自己想要的数据
data() {
return {
show:false,//商品规格弹框
price:'',//商品默认价格
stock_num:'',//商品默认总库存
if_sku:true,//判断该商品是否有规格
sku:[],//商品规格
skuPrice:[],//规格对应的价格和库存
select_id:[],//选中的规格id、组成的数组
select_id2:[],//选中的规格id、需要提交给后台
value:'',//商品购买数量
}
}
mounted(){
//在这里请求接口获取商品数据,我就不写了,直接写数据的处理逻辑
this.price = res.data.detail.price;//商品默认价格
this.stock_num = res.data.detail.amount;//商品默认总库存
// 商品分两种操作,一种无规格直接可以购买,一种有规格,需要判断先选择规格后才能操作
if(res.data.sku.length == 0){
//无规格
this.if_sku = false;
}else{
//有规格
this.if_sku = true;
res.data.sku.forEach(item=>{ // 这里的item 就是接口返回的 sku,
let obj = {
name:'', // 大规格名称:如颜色,尺寸
list:[], // 具体的大规格下的小规格,如颜色下边有黑色,白色
}
obj['name'] = item.standard.name,//大规格名称
obj['list'] = item.skuValues,//具体某个规格下的所有规格
obj.list.forEach(val=>{
this.$set(val,'active',false); // 新增active字段来判断当前选中高亮状态
})
this.sku.push(obj); // this.sku 用来循环渲染页面
})
}
}
我们重组后的数据格式如下
现在用该数据渲染html,这里只展示规格弹窗页面结构,具体样式就不再写了
<van-popup v-model="show" position="bottom" round>
<div class="title">
<img :src="detail.mainPic" alt="">
<div class="text">
<div class="price">¥<b>{{price}}</b></div>
<span>剩余 {{stock_num}}件</span>
<span>请选择商品规格</span>
</div>
</div>
<div class="content">
<div class="item" v-for="(item,index) in sku" :key="index">
<h2>{{item.name}}</h2>
<div class="val">
<!-- sku_id 方法,用来获取点击项,给对应的数据高亮显示,并拿到点击的id -->
<p @click="sku_id(val.id,index,i)" :class="{active:val.active==true}" v-for="(val,i) in item.list" :key="i">{{val.name}}</p>
</div>
</div>
<div class="num">
<p>购买数量</p>
<van-stepper min="1" v-model="value" />
</div>
<div class="btn">
<button @click="addCart">加入购物车</button>
<button @click="buy">立即购买</button>
</div>
</div>
</van-popup>
具体的sku_id()方法实现
sku_id(id,index,i){
/*
id:当前商品id、
index:大规格的索引,具体点击的是颜色,还是尺寸
i:小规格的索引,点击的是颜色规格下的黑色,还是白色,
这里的index和i、用来控制点击项的高亮展示,同时需要id、push进对应索引的 select_id[]
*/
/*
this.select_id[index]
1.如果此时你点击的是第一项:号码,那么 index == 0,循环this.sku[0].list
如果满足item.id == id 这个条件,就返回item这个数据,把该数据的id、赋值给this.select_id[0]
2.如果此时你点击的是第二项:颜色,那么 index == 1,循环this.sku[1].list
如果满足item.id == id 这个条件,就返回item这个数据,把该数据的id、赋值给this.select_id[1]
3.这样我们就拿到了[10,15] 这样的数据(黑色,43号),用这个数据去跟后台返回的skuPrice做对比,如果值相同,则展示对应的价格和库存
*/
this.select_id[index] = this.sku[index].list.filter(item=>{
return item.id == id ;
})[0].id;
// 点击的是哪个规格,在点击后的高亮处理
this.sku[index].list.forEach(item=>{
if(item.id == id ){
this.sku[index].list[i].active = true;
}else{
item.active = false;
}
})
/*
如果 select_id的length等于this.sku.length,说明此时规格已全部选择完毕,
开始和后台返回的 skuPrice 数据做对比,如果全部相等,则展示对应的价格和库存,
matchingArrays 就是当前选中项的价目表,
*/
this.matchingArrays = this.findMatchingData(this.select_id, this.skuPrice);
console.log(this.matchingArrays);
},
findMatchingData(input, target) {
for (const item of target) {
// 检查是否与输入数组1的sku_ids匹配
if (JSON.stringify(item.sku) === JSON.stringify(input)) {
return item; // 返回找到的匹配数据
}
}
return null; // 如果未找到匹配数据,返回null或者其他默认值
},
//写到这里,完整的规格选择已经做完了,下面是加入购物车,跟购买同理,只写下购物车操作
addCart(){
for(var i=0;i<this.sku.length;i++){
if(this.select_id[i] == undefined){
return this.$toast.fail('请选择完整规格')
}
}
if(Number(this.value)>Number(this.stock_num)){
this.$toast.fail('库存不足')
}else{
if(this.if_sku){
//有规格
if(this.select_id.length < this.sku.length){
this.$toast.fail('请选择商品规格')
}else{
let data = {
num:this.value,
productId:this.detail.id,
skuIds:this.select_id2,
}
getAddCart(data).then(res=>{
if(res.errCode == 100){
this.$toast.success('添加购物成功')
this.show = false;
}
})
}
}else{
//无规格
let data = {
num:this.value,
productId:this.detail.id,
skuIds:[],
}
getAddCart(data).then(res=>{
if(res.errCode == 100){
this.$toast.success('添加购物成功')
this.show = false;
}
})
}
}
},
更多推荐
已为社区贡献15条内容
所有评论(0)