微信小程序购物车简单实现:
1、商品单选及全选,全选不包括下架商品及库存不足商品;
2、商品单选及全选,同时计算商品总价及商品数量;
3、商品数量增加及减少,商品数量最少为1件;
4、商品数量增加减少时,同时计算商品总价及商品数量;
效果截图:
MOCK数据结构:
goodsList: [
{
id: '', //商品ID
name: '', // 商品名称
subtitle: '', // 商品副标题
image: '', // 商品图片
price: '', // 商品价格
num: '', // 商品数量
inventory: '', // 商品库存
selected: '', // 是否勾选
shelves: ''// 是否下架
}
]
以下为基本实现代码:
WXML代码:
<view class="container">
<view class="shopping-cart-content">
<view class="shopping-cart-edit">
<text bindtap="editShoppingCart">{{operateText}}</text>
</view>
<view class="shopping-cart-item" wx:for="{{goodsList}}" wx:key="index">
<view class="cart-item-radio" hidden="{{goodsCheckbox}}">
<!-- 库存小于1及已下架商品 不能选中 -->
<block wx:if="{{item.inventory < 1 || item.shelves == true}}">
<image src="https://oss.doctoryan.cn/wx/family/img/icon/shopping_not_choose_icon.png"></image>
</block>
<block wx:else>
<image src="{{item.selected == true ? 'https://oss.doctoryan.cn/wx/family/img/icon/shopping_choose_icon.png' : 'https://oss.doctoryan.cn/wx/family/img/icon/shopping_not_choose_icon.png'}}" data-index="{{index}}" catchtap="multipleChoice"></image>
</block>
</view>
<!-- 删除图标 -->
<view class="cart-item-radio" hidden="{{goodsDelete}}">
<image src="https://oss.doctoryan.cn/wx/family/img/icon/shopping_cart_delete_icon.png" data-id="{{item.id}}" catchtap="deleteGoods"></image>
</view>
<view class="cart-item-img">
<image src="{{item.image}}"></image>
</view>
<view class="cart-item-info">
<view class="item-info-title">{{item.name}}</view>
<view class="item-info-choose">{{item.subtitle}}</view>
<view class="item-info-other">
<!-- 价格 -->
<text class="text-red">¥{{item.price}}</text>
<view class="operate">
<!-- 已下架 -->
<block wx:if="{{item.shelves == true}}">
<text class="inventory">已下架</text>
</block>
<block wx:else>
<!-- 还有库存 可添加减少数量 -->
<block wx:if="{{item.inventory > 0}}">
<image class="minus" src="https://oss.doctoryan.cn/wx/family/img/icon/shopping_cart_minus_icon.png" data-index="{{index}}" catchtap="lessenNum"></image>
<text class="num text-center">{{item.num}}</text>
<image class="add" src="https://oss.doctoryan.cn/wx/family/img/icon/shopping_cart_add_icon.png" data-index="{{index}}" catchtap="augmentNum"></image>
</block>
<!-- 库存不足 -->
<text class="inventory" wx:else>库存不足</text>
</block>
</view>
<view class="clearfix"></view>
</view>
</view>
<view class="clearfix"></view>
</view>
</view>
<view class="shopping-cart-bottom">
<view class="select-all">
<image src="{{checked == true ? 'https://oss.doctoryan.cn/wx/family/img/icon/shopping_choose_icon.png' : 'https://oss.doctoryan.cn/wx/family/img/icon/shopping_not_choose_icon.png'}}" catchtap="selectAllGoods"></image> 全选
</view>
<view class="goods-price">
<text>合计:</text>
<text class="text-red">¥{{totalPrice}}</text>
</view>
<button class="settlement" bindtap="goodsSettlement">结算({{settlement}})</button>
</view>
</view>
WXSS代码:
.shopping-cart-content{padding:0 0 100rpx 0;}
.shopping-cart-edit{width: 95%;padding:20rpx 2.5%;}
.shopping-cart-item{width:95%;background-color: #fff;padding:5% 2.5%;display: flex;flex-wrap: wrap;margin:0 0 20rpx 0;}
.cart-item-radio{width: 70rpx;padding: 70rpx 0 0 0;}
.cart-item-radio image{width:43rpx;height:43rpx;padding: 4rpx 0 0 0;}
.cart-item-img{width:220rpx;}
.cart-item-img image{width: 200rpx;height: 200rpx;border-radius: 20rpx;}
.cart-item-info{width:calc(100% - 290rpx);}
.item-info-title{height:80rpx;display: block; text-align: justify;word-break:break-all;overflow:hidden;text-overflow:ellipsis;}
.item-info-choose{color: #a8a8a8;background-color: #f6f6f6;display:inline-block;border-radius: 40rpx;padding: 5rpx 10rpx;margin: 10rpx 0;font-size:26rpx;}
.item-info-other .text-red{font-weight: bold;font-size:34rpx;}
.item-info-other .operate{float: right;}
.item-info-other .operate .inventory{vertical-align: -5rpx;}
.item-info-other .operate .text-red{font-size:24rpx;}
.item-info-other .num{width:60rpx;display:inline-block;background-color: #f5f5f5;border-radius:10rpx;margin: 0 20rpx;}
.item-info-other .minus,.item-info-other .add{height:41rpx; width:40rpx;vertical-align: -8rpx;}
.shopping-cart-bottom{width: 95%;height: 100rpx;line-height:100rpx;background-color: #fff;position: fixed;bottom: 0;display: flex;padding: 0 2.5%;border-top: .5rpx solid #e5e5e5;}
.shopping-cart-bottom .select-all{flex: 1;width: 60rpx;}
.shopping-cart-bottom .select-all image{width: 40rpx;height: 40rpx;vertical-align: -9rpx;}
.shopping-cart-bottom .goods-price{flex: 0 0 40%;font-weight: bold;font-size:34rpx;}
.shopping-cart-bottom .settlement{flex: 1;height:60rpx;line-height:60rpx;margin:20rpx 0 0 0;border-radius:50rpx;font-size:32rpx;color:#fff;background-image:linear-gradient(100deg,#fd8649,#fb6e45,#fa5e42);}
JS代码:
Page({
/**
* 页面的初始数据
*/
data: {
goodsDelete: true, // 商品删除
operateText: '编辑',
checked: false, // 默认不全选
cartCount: '', // 加入购物车数量
totalPrice: '0.00', // 总价
settlement: 0, // 结算商品总数
goodsList: [
{
id: 1,
name: '德国平衡车KK平衡车儿童滑德国平衡车KK平衡车儿童滑',
subtitle: '竞赛炫酷白【送头盔+护具】',
image: '.../product/20200910/13afaebef48045a48c2add23d56e35b7.png',
price: 999,
num: 1,
inventory: 20,
selected: false,
shelves: false
},
{
id: 2,
name: '德国平衡车KK平衡车儿童滑德国平衡车KK平衡车儿童滑',
subtitle: '竞赛炫酷白【送头盔+护具】',
image: '.../product/20200910/13afaebef48045a48c2add23d56e35b7.png',
price: 333,
num: 2,
inventory: 20,
selected: false,
shelves: false
},
{
id: 3,
name: '德国平衡车KK平衡车儿童滑德国平衡车KK平衡车儿童滑',
subtitle: '竞赛炫酷白【送头盔+护具】',
image: '.../product/20200910/13afaebef48045a48c2add23d56e35b7.png',
price: 666,
num: 1,
inventory: 0,
selected: false,
shelves: false
},
{
id: 4,
name: '德国平衡车KK平衡车儿童滑德国平衡车KK平衡车儿童滑',
subtitle: '竞赛炫酷白【送头盔+护具】',
image: '.../product/20200910/13afaebef48045a48c2add23d56e35b7.png',
price: 666,
num: 1,
inventory: 0,
selected: false,
shelves: true
},
]
},
//编辑购物车
editShoppingCart: function(){
let that = this;
if(that.data.goodsDelete){
that.setData({
operateText: '完成',
goodsDelete: false,
goodsCheckbox: true,
selectAll: true
});
}else{
that.setData({
operateText: '编辑',
goodsDelete: true,
goodsCheckbox: false,
selectAll: false
});
}
},
// 单选
multipleChoice:function(e){
var that = this;
var index = e.currentTarget.dataset.index;
var goodsList = that.data.goodsList;
that.data.checked = true;
goodsList[index].selected = !goodsList[index].selected;
for (var i = goodsList.length - 1; i >= 0; i--) {
if (!goodsList[i].selected) {
that.data.checked = false;
break;
}
}
that.setData({
goodsList: goodsList,
checked: that.data.checked
});
that.countTotalPrice();
},
// 全选
selectAllGoods: function(e){
let that = this;
if(that.data.operateText == '编辑'){
let checked = that.data.checked;
checked = !checked;
let goodsList = that.data.goodsList;
for (let i = 0; i < goodsList.length; i++) {
if (goodsList[i].inventory > 0 && goodsList[i].shelves == false){
goodsList[i].selected = checked;
}
}
this.setData({
checked: checked,
goodsList: goodsList
});
that.countTotalPrice();
}
},
// 计算总价
countTotalPrice: function(){
let that = this;
let goodsList = that.data.goodsList;
let prc = 0.0;
let snum = 0;
for (let i = 0; i < goodsList.length; i++) {
if (goodsList[i].selected && goodsList[i].inventory > 0 && goodsList[i].shelves == false){
prc += goodsList[i].num * goodsList[i].price;
snum += goodsList[i].num;
}
}
that.setData({
goodsList: goodsList,
totalPrice: prc.toFixed(2),
settlement: snum
})
},
//商品删除
deleteGoods: function(e){
let id = e.currentTarget.dataset.id;
wx.showToast({
title: '删除商品',
icon: 'none'
});
// ... other code
},
//商品数量增加
augmentNum: function(e){
var that = this;
let index = e.currentTarget.dataset.index;
let goodsList = that.data.goodsList;
let num = that.data.goodsList[index].num;
num = num + 1;
goodsList[index].num = num;
that.setData({
goodsList: goodsList
});
that.countTotalPrice();
},
//商品数量减少
lessenNum: function(e){
var that = this;
let index = e.currentTarget.dataset.index;
let goodsList = that.data.goodsList;
let num = goodsList[index].num;
if (num <= 1){
return false;
}
num = num - 1;
goodsList[index].num = num;
that.setData({
goodsList: goodsList,
count: that.data.goodsList[index].num,
});
that.countTotalPrice();
},
// 商品结算
goodsSettlement: function(){
let that = this;
wx.showToast({
title: '当前选择了' + that.data.settlement + '件商品,共计' + that.data.totalPrice + '元RMB',
icon: 'none'
});
// other code
}
})