uniapp商品详情页规格、SKU选择

uniapp商品详情页购物车选择

提示:这里因为后台返回的数据格式原因,代码性能可能有点稍差,但是注释是很完整的


文章目录

  • uniapp商品详情页购物车选择
  • 先上代码,以示诚意
  • 后台接口返回的数据格式
  • 实现讲解


先上代码,以示诚意

<template>
  <view>
		<!-- 循环 -->
    <view class="sku-list" v-for="item in this.userChooseSkuList" :key="item.id">
			<!-- sku标题 -->
			<view class="sku-title">{{item.skuTitle}}</view>
			<!-- 供用户选择的skuLabel -->
			<view class="sku-label-list">
				<view class="label"v-for="(label,index) in item.skuList"
							@tap="skuLabelClick(item,label,index)"
							 :key="label.id" :class="{'active':label.checked}">
					{{label.labelText}}</view>
			</view>
		</view>
  </view>
</template>

<script>
export default {
  data () {
    return {
    	// 接口返回的SUK列表
      skuHttpList: {
        尺码: ['S', 'M', 'L', 'XL', 'XXL'],
        颜色: ['红色', '蓝色', '绿色', '紫色', '橙色', '黑色'],
        套装: ['全身', '半身', '上装', '下装']
      },
			// 组织好的参数,用来循环供用户选择的sku列表
			userChooseSkuList:[],
			// 用户选择中的sku对象
			userChooseSku: {},
			// 接口返回的sku列表
			httpSkus: [
				{
					'id': 1,
					'price': '0.00',
					'marketPrice': '0.00',
					'costPrice': '0.00',
					'stock': 0,
					'productId': 55,
					'productSpecs': {
						'尺码': 'S',
						'颜色':'红色',
						'套装':'全身'
					},
					'status': 1
				},{
					'id': 2,
					'price': '0.00',
					'marketPrice': '0.00',
					'costPrice': '0.00',
					'stock': 0,
					'productId': 55,
					'productSpecs': {
						'尺码': 'M',
						'颜色':'蓝色',
						'套装':'上装'
					},
					'status': 1
				},{
					'id': 3,
					'price': '0.00',
					'marketPrice': '0.00',
					'costPrice': '0.00',
					'stock': 0,
					'productId': 55,
					'productSpecs': {
						'尺码': 'XL',
						'颜色':'橙色',
						'套装':'全身'
					},
					'status': 1
				},{
					'id': 4,
					'price': '0.00',
					'marketPrice': '0.00',
					'costPrice': '0.00',
					'stock': 0,
					'productId': 55,
					'productSpecs': {
						'尺码': 'L',
						'颜色':'绿色',
						'套装':'下装'
					},
					'status': 1
				},{
					'id': 5,
					'price': '0.00',
					'marketPrice': '0.00',
					'costPrice': '0.00',
					'stock': 0,
					'productId': 55,
					'productSpecs': {
						'尺码': 'XXL',
						'颜色':'黑色',
						'套装':'半身'
					},
					'status': 1
				},
			]
    }
  },
  onLoad () {
    this.initData()
  },
  methods: {
    // 页面初始化加载方法
    initData () {
      this.getShopInfo()
    },
		/* 这里调用接口,然后组织参数 */
    getShopInfo () {
    	// skuLabelId是一个自定义的id,因为uniapp在微信小程序上面双层循环用index会报错,所以生成一个自定义的保存id
    	let skuLabelId = 0
			for (let skuI in this.skuHttpList){
				// 每次循环,自定义的变量id自增,防止重复
				++skuLabelId

				// 这里skuI是获取所有的键
				console.log(skuI)

				// 定义一个对象,用来存储生成可循环的SKU
				let skuObj={
					id:skuLabelId,
					skuTitle:skuI,
					skuList:[],
				}

				// 这里组织sku列表
				for(let j= 0;j<this.skuHttpList[skuI].length;j++){
						// 把接口返回的SUK列表skuHttpList里面的值放到skuObj的skuList里面
					skuObj.skuList.push({
						id:skuLabelId+j,
						checked:false,
						labelText:this.skuHttpList[skuI][j]
					})
				}
				// 这里就是组合好的参数了,用来v-for循环
				this.userChooseSkuList.push(skuObj)
				console.log(this.userChooseSkuList)
			}
    },
		// 标签的点击事件
		skuLabelClick(skuRow,skuLabel,index){
			console.log(skuRow)
			console.log(skuLabel)
			console.log(index)
			// todo 这里其实可以用vue中的$set方法
			// 先把点击那一列checked重置为false
			skuRow.skuList.map(item=>{
				item.checked = false
			})
			// 然后让点击的那一个checked变为true(这里已经实现规格选择了)
			skuRow.skuList[index].checked = true

			// 组织合并用户点击的sku,和接口返回的sku列表做比较,显示用户选中的规格
			this.userChooseSku[skuRow.skuTitle] =skuLabel.labelText
			console.log(this.userChooseSku)

			this.httpSkus.forEach(item=>{
				// 调用对象比较的方法,确定是哪个sku
				if(this.isObjectValueEqualNew(this.userChooseSku,item.productSpecs)){
					/*
					* 目前写的是静态的数据,只有这5个能匹配到
					* '尺码': 'S',			'尺码': 'M'		'尺码': 'XL'		'尺码': 'L'		'尺码': 'XXL',
						'颜色':'红色'			'颜色':'蓝色'		'颜色':'橙色'		'颜色':'绿色'		'颜色':'黑色',
						'套装':'全身'			'套装':'上装'		'套装':'全身'		'套装':'下装'		'套装':'半身'
					* */
					// 这里的item就是匹配到的值了
					console.log(item)
				}
			})
		},

		// 判断对象键和值是否相等
		isObjectValueEqualNew(a, b) {
			// 判断两个对象是否指向同一内存,指向同一内存返回true
			if (a === b) return true;
			// 获取两个对象键值数组
			let aProps = Object.getOwnPropertyNames(a);
			let bProps = Object.getOwnPropertyNames(b);
			// 判断两个对象键值数组长度是否一致,不一致返回false
			if (aProps.length !== bProps.length) return false;
			// 遍历对象的键值
			for (let prop in a) {
				// 判断a的键值,在b中是否存在,不存在,返回false
				if (b.hasOwnProperty(prop)) {
					// 判断a的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回false
					if (typeof a[prop] === 'object') {
						if (!isObjectValueEqual(a[prop], b[prop])) return false;
					} else if (a[prop] !== b[prop]) {
						return false;
					}
				} else {
					return false;
				}
			}
			return true;
		},
  }
}
</script>

<style>
		.sku-list{
			margin-bottom: 20rpx;
		}
	.sku-title{
		font-weight: bold;
	}
	.sku-label-list{
		display: flex;
		justify-content: left;
	}
	.label{
		padding: 10rpx 20rpx;
		margin-right: 20rpx;
		height: 60rpx;
		line-height: 60rpx;
		background: #f5f5f5;
		border-radius: 4rpx;
	}
	.label.active{
		background: #2f8eed;
		color: #FFFFFF;
	}
</style>

这是实现的大致效果
uniapp商品详情页规格、SKU选择_第1张图片

后台接口返回的数据格式

这是后台返回供用户选择的SKU列表,对应的就是代码里面的skuHttpList
uniapp商品详情页规格、SKU选择_第2张图片
这是后台返回组合后SKU的数据
uniapp商品详情页规格、SKU选择_第3张图片

实现讲解

注释已经写的很清楚了,不用上讲解了,嘻嘻

你可能感兴趣的:(uni-app,javascript)