vue商城:商品规格数据处理

后台接口返回的数据结构

在这里插入图片描述

在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 数据做对比,如果全部相等,则展示对应的价格和库存,
	 此处有个BUG,不可以使用 sort() 排序方法去对比,会打乱 select_id[]原本的索引对应关系
	*/

	// arr : 如果我们选择后的规格数组id、和接口返回的skuPrice中的某一项全等,就返回skuPrice中全等的数据
	let arr = this.skuPrice.filter(item=>{
			return this.select_id.length === item.sku.length && this.select_id.every(a => item.sku.some(b => a === b)) && item.sku.every(_b => this.select_id.some(_a => _a === _b));
		})
	
	if(arr.length == 0){
		this.stock_num = 0; // 没有库存
	}else{
		// select_id2是提交给后台的数据,因为后台要求,id顺序必须与接口返回的一直,所以重新复制出了一个select_id2
		// 我们自己选择后拼成的数组是 select_id,
		// 这里有个BUG 不能使用select_id数组,原因也是会打乱原本的索引对应关系
		this.select_id2 = arr[0].sku;// 
		this.price = arr[0].price;//商品价格
		this.stock_num = arr[0].amount;//商品库存
	}
	
},

//写到这里,完整的规格选择已经做完了,下面是加入购物车,跟购买同理,只写下购物车操作

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;
				}
			})
		}
	}
},

猜你喜欢

转载自blog.csdn.net/qq_40745143/article/details/105805245
今日推荐