Blogger Information
Blog 17
fans 0
comment 0
visits 7600
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
使用APICloud AVM框架封装SKU(商品规格选择)组件
P粉132815477
Original
512 people have browsed it

本文介绍使用APICloud AVM框架封装SKU(商品规格选择)组件,该SKU组件可实现商品图片与颜色属性进行联动,通过颜色、版本来控制价格,总价通过买入数量与所选商品价格进行自动计算;可进行缺货设定。


上述功能点是通过商品数据结构和代码逻辑进行配合来实现的。


商品数据结构如下:


goodsList:[

{id:'100016015112',

image:'https://m.360buyimg.com/mobilecms/s750x750_jfs/t1/210630/17/8651/208682/618a5bd6Eddc8ea0e/b5e55e1a03bc0126.jpg!q80.dpg.web',

color:'亮黑色',

status:true,

guige:[

{label:'8G+128G',price:'3999',status:false},

{label:'8G+256G',price:'5999',status:true},

{label:'16G+512G',price:'6999',status:true},

{label:'16G+1024G',price:'9999',status:false}

]},

{id:'100016015113',

image:'https://img14.360buyimg.com/n4/jfs/t1/216079/14/3895/201095/618a5c0cEe0b9e2ba/cf5b98fb6128a09e.jpg',

color:'釉白色',

status:true,

guige:[

{label:'8G+128G',price:'3799',status:true},

{label:'8G+256G',price:'5799',status:true},

{label:'16G+512G',price:'6799',status:true},

{label:'16G+1024G',price:'9799',status:false}

]},

{id:'100016015132',

image:'https://img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg',

color:'秘银色',

status:true,

                guige:[

{label:'8G+128G',price:'3599',status:true},

{label:'8G+256G',price:'5599',status:true},

{label:'16G+512G',price:'6599',status:true},

{label:'16G+1024G',price:'9599',status:false}

]},

{id:'200016015117',

image:'https://img14.360buyimg.com/n4/jfs/t1/203247/8/14659/237368/618a5c87Ecc968774/b0bb25331e5e2d1a.jpg',

color:'夏日胡杨',

                status:false,

guige:[

{label:'8G+128G',price:'3899',status:false},

{label:'8G+256G',price:'5899',status:false},

{label:'16G+512G',price:'6899',status:false},

{label:'16G+1024G',price:'9899',status:false}

]},

{id:'100013415456',

image:'https://img14.360buyimg.com/n4/jfs/t1/160950/40/25098/234168/618a5cb9E65ba975e/7f8f93ea7767a51b.jpg',

color:'冬日暖阳',

status:true,

                guige:[

{label:'8G+128G',price:'3199',status:true},

{label:'8G+256G',price:'5199',status:true},

{label:'16G+512G',price:'6199',status:true},

{label:'16G+1024G',price:'9199',status:false}

]}

]

每个商品的版本有多条数据,每条数据都对应不同的价格,同时会有字段标识是否有货。


每一个商品也会有字段标识是否有货。


当切换商品属性时,需要通过函数进行判断,以保证在商品缺货的情况下,不能被选中。


setGoods(e){

// console.log(JSON.stringify(e));

let item = e.currentTarget.dataset.item;

if(item.status){

this.data.selectGoods = item;

this.data.guigeList = item.guige;

for (let index = 0; index <  item.guige.length; index++) {

const element = item.guige[index];

             //保证默认选中的商品是有货的

if(element.status){

this.data.selectGuige = element;

break;

}

}

}

},

组件文件

easy-sku.stml


<template>

<view class="easy-sku_container">

<view class="easy-sku_box">

<view class="easy-sku_base">

<view class="easy-sku_base-pic-box">

<image class="easy-sku_base-pic" src={selectGoods.image} mode="widthFix"></image>

</view>

<view class="easy-sku_base-info">

<text class="easy-sku_base-info-price">¥{selectGuige.price?selectGuige.price*count:0}</text>

<text class="easy-sku_base-info-num">商品编号:{selectGoods.id}</text>

</view>

<view class="easy-sku_close-box" @click="cancel">

<image class="easy-sku_close-ico" src={ico_close} mode="widthFix"></image>

</view>

</view>

<scroll-view class="easy-sku_scroll-box" scroll-y>

<view class="easy-sku_guige-box">

<view class="easy-sku_guige-title">

<text class="easy-sku_guige-title-label">颜色</text>

</view>

<view class="easy-sku_guige-item-box">

<view :class="selectGoods.id==item.id?'easy-sku_guige-item--select':'easy-sku_guige-item--default'" v-for="(item,index) in goodsList" data-item={item} @click="setGoods">

<text :class="selectGoods.id==item.id?'easy-sku_guige-item-label-select':item.status?'easy-sku_guige-item-label--default':'easy-sku_guige-item-label-disable'">{item.color}</text>

</view>

</view>

</view>

<view class="easy-sku_guige-box">

<view class="easy-sku_guige-title">

<text class="easy-sku_guige-title-label">版本</text>

</view>

<view class="easy-sku_guige-item-box">

<view :class="selectGuige.label==item.label?'easy-sku_guige-item--select':'easy-sku_guige-item--default'" v-for="(item,index) in guigeList" data-item={item} @click="setGuige">

<text :class="selectGuige.label==item.label?'easy-sku_guige-item-label-select':item.status?'easy-sku_guige-item-label--default':'easy-sku_guige-item-label-disable'">{item.label}</text>

</view>

</view>

</view>

<view class="easy-sku_count-box">

<text class="easy-sku_count-label">买入数量</text>

<view class="easy-sku_count-result-tool">

<text :class="count>0?'easy-sku_count-result-item':'easy-sku_count-result-item--disable'" @click="countDel">-</text>

<input class="easy-sku_count-result-input" placeholder="" keyboard-type="number" v-model="count"/>

<text class="easy-sku_count-result-item" @click="countAdd">+</text>

</view>

</view>

</scroll-view>

<view class="easy-sku_bottom">

<button class="easy-sku_btn" @click="submit">确认</button>

</view>

<safe-area></safe-area>

</view>

</view>

</template>

<script>

export default {

name: 'easy-sku',

installed(){

this.data.selectGoods=this.props.goodsList[0];

// this.data.selectGuige=this.props.goodsList[0].guige[1];

this.data.guigeList = this.props.goodsList[0].guige;

},

props:{

goodsList:Array,

},

data() {

return{

ico_close:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAjUlEQVR42mNgGNlg1qxZbTNnzrxFgvqnQJyLUwHQsKtA/B+InxEyDKjmI0gt0MD9hBQ+ImQozDAgvkyUV/AZSrJh+Awl2zBshlJsGBZDKTcMmjR+Ihn4kVqGHQS5jiJDkQ1D8j55hmIzjGxD8RlGsqFABe8IGYbF0Pv4FAUAXbiIhCS1ac6cOXYjvEwFAL7uy3s7L72GAAAAAElFTkSuQmCC',

selectGoods:{},

selectGuige:{},

count:1,

guigeList:[]

}

},

methods: {

setGoods(e){

// console.log(JSON.stringify(e));

let item = e.currentTarget.dataset.item;

if(item.status){

this.data.selectGoods = item;

this.data.guigeList = item.guige;

for (let index = 0; index <  item.guige.length; index++) {

const element = item.guige[index];

if(element.status){

this.data.selectGuige = element;

break;

}

}

}

},

setGuige(e){

// console.log(JSON.stringify(e));

let item = e.currentTarget.dataset.item;

if(item.status){

this.data.selectGuige = item;

}

},

countAdd(){

this.data.count++;

},

countDel(){

if(this.data.count>0){

this.data.count--;

}

},

cancel(){

this.fire('cancel','');

},

submit(){

this.fire('submit',{goods:this.data.selectGoods,guige:this.data.selectGuige,count:this.data.count});

}

}

}

</script>

<style>

.easy-sku_container {

position: absolute;

height: 100%;

width: 100%;

background-color: rgba(0,0,0,0.1);

}

.easy-sku_box{

align-items: center;

justify-content: space-between;

position: absolute;

bottom: 0;

width: 100%;

height: 70%;

background-color: #ffffff;

border-top-left-radius: 30px;

border-top-right-radius: 30px;

padding: 15px;

}

.easy-sku_base{

width: 100%;

padding: 15px;

}

.easy-sku_base-pic{

width: 80px;

height: 80px;

}

.easy-sku_base{

flex-flow: row nowrap;

justify-content: space-between;

align-items: flex-end;

}

.easy-sku_base-info{

flex: 1;

padding-left: 10px;

}

.easy-sku_base-info-price{

color: #fa2c19;

font-size: 16px;

}

.easy-sku_base-info-num{

color: #666666;

font-size: 12px;

}

.easy-sku_close-box{

height: 100%;

}

.easy-sku_close-ico{

width: 20px;

}

.easy-sku_scroll-box{

width: 100%;

flex: 1;

}

.easy-sku_guige-box{

width: 100%;

}

.easy-sku_guige-title{

padding: 10px 0;

}

.easy-sku_guige-title-label{

font-size: 16px;

font-weight: bolder;

}

.easy-sku_guige-item-box{

flex-flow: row wrap;

justify-content: flex-start;

align-items: center;

}

.easy-sku_guige-item--default{

background-color: #f2f2f2;

border: 0.5px solid #f2f2f2;

border-radius: 18px;

padding: 8px 18px;

margin-right: 10px;

margin-bottom: 10px;

}

.easy-sku_guige-item-label--default{

font-size: 14px;

color: #333333;

}

.easy-sku_guige-item--select{

background-color: #fee0dd;

border: 0.5px solid #fa2c19;

border-radius: 18px;

padding: 8px 18px;

margin-right: 10px;

margin-bottom: 10px;

}

.easy-sku_guige-item-label-select{

font-size: 14px;

color: #fa2c19;

}

.easy-sku_guige-item-label-disable{

font-size: 14px;

color: #b5b5b5;

/* text-decoration: line-through; */

}

.easy-sku_count-box{

width: 100%;

flex-flow: row nowrap;

justify-content: space-between;

align-items: center;

margin-top: 10px;

}

.easy-sku_count-result-tool{

flex-flow: row nowrap;

justify-content: space-between;

align-items: center;

}

.easy-sku_count-result-item{

font-size: 25px;

padding: 0 5px;

color: #333333;

}

.easy-sku_count-result-item--disable{

font-size: 25px;

padding: 0 5px;

color: #b5b5b5;

}

.easy-sku_count-result-input{

background-color: #f0f0f0;

border: 0;

height: 18px;

width: 40px;

text-align: center;

border-radius: 5px;

}

.easy-sku_count-label{

font-size: 16px;

color: #333333;

}

.easy-sku_bottom{

width: 100%;

}

.easy-sku_btn{

background-color: #fa2c19;

border-radius: 21px;

font-size: 15px;

color: #fff;

padding: 10px;

}

</style>


示例文件

demo-easy-sku.stml


<template>

<view class="page">

<safe-area></safe-area>

<view class="item" @click="openSKU">

<text>选择商品</text>

</view>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

<easy-sku

oncancel="closeSKU"

onsubmit="getSKU"

:goodsList="goodsList"

v-if="isShow"

>

</easy-sku>

</view>

</template>

<script>

import '../../components/easy-sku.stml'

export default {

name: 'demo-easy-sku',

apiready(){//like created

 

},

data() {

return{

isShow:false,

goodsList:[

{id:'100016015112',

image:'https://m.360buyimg.com/mobilecms/s750x750_jfs/t1/210630/17/8651/208682/618a5bd6Eddc8ea0e/b5e55e1a03bc0126.jpg!q80.dpg.web',

color:'亮黑色',

status:true,

guige:[

{label:'8G+128G',price:'3999',status:false},

{label:'8G+256G',price:'5999',status:true},

{label:'16G+512G',price:'6999',status:true},

{label:'16G+1024G',price:'9999',status:false}

]},

{id:'100016015113',

image:'https://img14.360buyimg.com/n4/jfs/t1/216079/14/3895/201095/618a5c0cEe0b9e2ba/cf5b98fb6128a09e.jpg',

color:'釉白色',

status:true,

guige:[

{label:'8G+128G',price:'3799',status:true},

{label:'8G+256G',price:'5799',status:true},

{label:'16G+512G',price:'6799',status:true},

{label:'16G+1024G',price:'9799',status:false}

]},

{id:'100016015132',

image:'https://img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg',

color:'秘银色',

status:true,guige:[

{label:'8G+128G',price:'3599',status:true},

{label:'8G+256G',price:'5599',status:true},

{label:'16G+512G',price:'6599',status:true},

{label:'16G+1024G',price:'9599',status:false}

]},

{id:'200016015117',

image:'https://img14.360buyimg.com/n4/jfs/t1/203247/8/14659/237368/618a5c87Ecc968774/b0bb25331e5e2d1a.jpg',

color:'夏日胡杨',status:false,

guige:[

{label:'8G+128G',price:'3899',status:false},

{label:'8G+256G',price:'5899',status:false},

{label:'16G+512G',price:'6899',status:false},

{label:'16G+1024G',price:'9899',status:false}

]},

{id:'100013415456',

image:'https://img14.360buyimg.com/n4/jfs/t1/160950/40/25098/234168/618a5cb9E65ba975e/7f8f93ea7767a51b.jpg',

color:'冬日暖阳',

status:true,guige:[

{label:'8G+128G',price:'3199',status:true},

{label:'8G+256G',price:'5199',status:true},

{label:'16G+512G',price:'6199',status:true},

{label:'16G+1024G',price:'9199',status:false}

]}

],

}

},

methods: {

openSKU(){

this.data.isShow=true;

},

closeSKU(){

this.data.isShow=false;

},

getSKU(e){

console.log(JSON.stringify(e));

api.toast({

msg:'颜色:'+e.detail.goods.color+'/规格:'+e.detail.guige.label+'/数量:'+e.detail.count+'/总价:'+e.detail.count*e.detail.guige.price,

location:'middle'

})

this.data.isShow = false;

}

}

}

</script>

<style>

.page {

height: 100%;

background-color: #f6f6f6;

}

.item{

background-color: #ffffff;

margin: 15px;

padding: 15px;

border-radius: 5px;

}

</style>


点击立即使用AVM框架


Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post