uni-app类似淘宝选择商品多规格(库存判断)
Posted GHUIJS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app类似淘宝选择商品多规格(库存判断)相关的知识,希望对你有一定的参考价值。
1.组件效果展示
瞎封装组件系列:
2.使用方法
引入组件:
import goodsSpec from '@/components/goodsSpec.vue'
在<template>合适的区域使用
<button type="default" @click="isShow = true">选择规格</button>
<goods-spec v-if="goodsDate" :isShow="isShow" :goodsData="goodsDate" @hiddenModal='hiddenModal'></goods-spec>
组件规定需要从父组件传商品规格信息的JSON,和一个布尔值,控制规格选择弹出框显示状态。
商品规格信息JSON必须符合组件规定标准,例子中的数据模拟接口地址是:
https://www.fastmock.site/mock/961b619357977ecee63001f0f5140734/yghh/goodsSkuTree
例子源码:
<template>
<view>
<button type="default" @click="isShow = true">选择规格</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.代码实现
实现原理:
点击规格按钮时,把所选规格装到一个数组中,最后把组合的规格代入商品数量的json中查找。
<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>库存{{currentItem.stock || 0}}件</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: '不可点击',
type: 'warning',
time: 1500
})">{{item.name}}</span>
</view>
</view>
</view>
</view>
</view>
</transition>
</template>
<script>
export default {
name: "goodsSpec",
data() {
return {
skuInfo: [],
selectArr: [], //当前已选规格数组
specShowString: '选择规格', //已选规格字符串展示
currentItem: {
price: 0,
stock: 0
}, //规格选完后的对象
subIndex: [] //规格选中样式
};
},
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 当前点击规格按钮的值(黑色,35)
* @param {Number} specIndex 选择的规格下标(例子中颜色是0,尺码是1)
* @param {Number} specItemIndex 选择规格值下标(例子中35下标是0)
*/
specificationBtn(specName, specIndex, specItemIndex) {
if (this.selectArr[specIndex] != specName) {//判断所选规格数组中是否包含当前点击规格
this.selectArr[specIndex] = specName;//如果没有则把当前规格添加
this.subIndex[specIndex] = specItemIndex;//添加选中样式
} else {
this.selectArr[specIndex] = '';
this.subIndex[specIndex] = -1;//去除样式
}
this.specShowString = this.spaceRemoveArr(this.selectArr).join(';') || '选择规格';//所选规格页面中展示,数组为空则变为选择规格
this.inventoryLookup();//当规格选完后,去匹配
this.clickPitch();//库存判断,实现不可点击
},
spaceRemoveArr(arr) {//数组去除空字符串
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] : '';
}
//最难理解的大概就是这里了,这里跟着循环里打印结果,多走几遍就大致明白了 假象.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>
写的不好,多多指教。
以上是关于uni-app类似淘宝选择商品多规格(库存判断)的主要内容,如果未能解决你的问题,请参考以下文章