当前位置:网站首页>Uni app is similar to Taobao in selecting multiple specifications of commodities (inventory judgment)

Uni app is similar to Taobao in selecting multiple specifications of commodities (inventory judgment)

2022-06-26 07:48:00 GHUIJS

 1. Component effect display


Blind package component series :

VUE Simple prompt box

VUE Tree diagram ( Recursive implementation )

VUE Multi store shopping cart

 2. Usage method

Import components :

import goodsSpec from '@/components/goodsSpec.vue'

stay <template> Use in appropriate areas

<button type="default" @click="isShow = true"> Select specifications </button>
<goods-spec v-if="goodsDate" :isShow="isShow" :goodsData="goodsDate" @hiddenModal='hiddenModal'></goods-spec>

The component specifies that the product specification information needs to be transferred from the parent component JSON, And a Boolean value , The control specification selection pop-up box displays the status .

Product specification information JSON Must comply with the standards specified for the component , The address of the data simulation interface in the example is :

https://www.fastmock.site/mock/961b619357977ecee63001f0f5140734/yghh/goodsSkuTree

Example source code :

<template>
	<view>
<button type="default" @click="isShow = true"> Select specifications </button>
<goods-spec v-if="goodsDate" :isShow="isShow" :goodsData="goodsDate" @hiddenModal='hiddenModal'></goods-spec>
	</view>
</template>

<script>
	import goodsSpec from '@/components/goodsSpec.vue'
	export default {
		data() {
			return {
				list:[],
				goodsDate:null,
				isShow:false
			}
		},
		created() {
			// https://www.fastmock.site/mock/961b619357977ecee63001f0f5140734/yghh/goodsSkuTree
			this.$request.get('/goodsSkuTree').then(res => {
				this.goodsDate = res.data;
			})
		},
		components:{
			goodsSpec
		},
		methods: {
			hiddenModal(){
				this.isShow = false
			}
		}
	}
</script>

<style>

</style>

3. Code implementation

Realization principle :

When you click the specification button , Load the selected specifications into an array , Finally, the combined specifications are substituted into the product quantity json Search for .

<template>
	<transition name="fade">
		<view class="spec-shade" v-if="isShow" @click.self="hiddenModal">
			<view class="spec-cont">
				<view class="goods-choose-show flex-star">
					<img src="../static/img/mba_banner3.jpg">
					<view class="goods-choose-show-right" v-if="currentItem">
						<p>¥{
   {currentItem.price || 0}}</p>
						<view> stock {
   {currentItem.stock || 0}} Pieces of </view>
						<view>{
   {specShowString}}</view>
					</view>
					<i class="iconfont icon-cuowu" @click.stop='hiddenModal'></i>
				</view>
				<view class="spec-linebox">
					<view class="spec-item" v-for="(skuItem,skuIndex) in skuInfo">
						<p>{
   {skuItem.name}}</p>
						<view class="item-cont flex-star">
							<span v-for="(item,index) in skuItem.items"
								:class="[item.isShow ? '' : 'noProduct',subIndex[skuIndex] == index ? 'act' : '']"
								@click="item.isShow ? specificationBtn(item.name,skuIndex,index) : $msg({
									msg: ' Do not click ',
									type: 'warning',
									time: 1500
								})">{
   {item.name}}</span>
						</view>
					</view>
				</view>
			</view>
		</view>
	</transition>	
</template>

<script>
	export default {
		name: "goodsSpec",
		data() {
			return {
				skuInfo: [],
				selectArr: [], // Currently selected specification array 
				specShowString: ' Select specifications ', // The selected specification string shows 
				currentItem: {
					price: 0,
					stock: 0
				}, // The object after the specification is selected 
				subIndex: [] // Specification selected style 
			};
		},
		props: {
			goodsData: {
				type: Object,
				required: true
			},
			isShow: false
		},
		created() {
			this.skuInfo = this.goodsData.SKUInfo;
			this.skuInfo.forEach(item => {
				item.items.forEach(specItem => {
					specItem.isShow = true;
				})
			})
		},
		methods: {
			hiddenModal(){
				this.$emit('hiddenModal',false)
			},
			/**
			 * @param {String} specName  The value of the currently clicked specification button ( black ,35)
			 * @param {Number} specIndex  Selected specification subscript ( The color in the example is 0, The size is 1)
			 * @param {Number} specItemIndex  Select the specification value subscript ( In the example 35 The subscript is 0)
			 */
			specificationBtn(specName, specIndex, specItemIndex) {
				if (this.selectArr[specIndex] != specName) {// Judge whether the selected specification array contains the currently clicked specification 
					this.selectArr[specIndex] = specName;// If not, add the current specification 
					this.subIndex[specIndex] = specItemIndex;// Add selected style 
				} else {
					this.selectArr[specIndex] = '';
					this.subIndex[specIndex] = -1;// Remove the pattern 
				}
				this.specShowString = this.spaceRemoveArr(this.selectArr).join(';') || ' Select specifications ';// The selected specification page shows , If the array is empty, it becomes the selection specification 
				this.inventoryLookup();// When the specifications are selected , To match 
				this.clickPitch();// Inventory judgment , Implementation is not clickable 
			},
			spaceRemoveArr(arr) {// Array removes empty strings 
				let tempArr = []
				arr.forEach(item => {
					if (item) {
						tempArr.push(item)
					}
				})
				return tempArr;
			},
			inventoryLookup() {
				try {
					this.goodsData.priceInfo.forEach((item, index) => {
						if (item.difference == this.specShowString) {
							this.currentItem = item;
							throw new Error();
						} else {
							this.currentItem = {
								SKU: '',
								price: 0,
								stock: 0
							};
						}
					})
				} catch (e) {}
			},
			clickPitch() {
				let result = [];
				for (let i in this.goodsData.SKUInfo) {
					result[i] = this.selectArr[i] ? this.selectArr[i] : '';
				}
				
				// The most difficult thing to understand is probably here , Here is the result printed in the loop , Walk a few more times and you'll get a general idea    illusion .jpg
				for (let i in this.goodsData.SKUInfo) {
					let last = result[i];
					console.log(result,'****************')
					for (let k in this.goodsData.SKUInfo[i].items) {
						result[i] = this.goodsData.SKUInfo[i].items[k].name;
						console.log(result,last)
						this.skuInfo[i].items[k].isShow = this.isMay(result)
					}
					result[i] = last;
				}
			},
			isMay(result) {
				for (let i in result) {
					if (result[i] == '') {
						return true;
					}
				}
				for (let i in this.goodsData.priceInfo) {
					if(this.goodsData.priceInfo[i].difference == result.join(";") && this.goodsData.priceInfo[i].stock > 0){
						return true;
					}
				}
			}
		},
		computed: {}
	}
</script>

<style lang="scss" scoped>
	.fade-enter-active, .fade-leave-active {
	  transition: opacity .5s;
	}
	.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
	  opacity: 0;
	}
	
	.spec-shade {
		position: fixed;
		left: 0;
		top: 0;
		bottom: 0;
		right: 0;
		background: rgba(0, 0, 0, .1);

		.spec-cont {
			background: white;
			position: absolute;
			bottom: 0;
			left: 0;
			width: 100%;
			padding: 20upx;

			.goods-choose-show {
				margin: -40upx 0 10upx 0;

				img {
					width: 180upx;
					height: 180upx;
					box-shadow: 0 0 10px rgba(0, 0, 0, .2);
					border-radius: 10upx;
					margin-right: 20upx;
					border: 5upx solid #fff;
				}

				.goods-choose-show-right {
					position: relative;

					p {
						color: #FE9E01;
						font-size: 32upx;
						font-weight: bold;
					}

					view {
						color: #666;
						font-size: 26upx;
						margin-top: 5upx;
					}
				}

				i.icon-cuowu {
					position: absolute;
					top: 30upx;
					right: 30upx;
				}
			}

			.spec-item {
				padding: 15upx 0;
				border-bottom: 1px solid #eee;

				p {
					font-weight: bold;
					line-height: 50upx;
				}

				.item-cont {
					padding: 15upx 0;

					span {
						display: inline-block;
						padding: 10upx 18upx;
						border-radius: 8upx;
						color: #666;
						font-size: 36upx;
						background: #F6F4F5;
						margin-right: 15upx;
					}

					span.act {
						background: #FDAB27;
						color: white;
					}

					span.noProduct {
						color: #ccc;
					}
				}
			}


		}
	}
</style>

Writing is not good , Your smile .

原网站

版权声明
本文为[GHUIJS]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202170609328537.html