程序商城系列之购物车
程序员文章站
2022-05-22 20:57:37
...
购物车功能基本上算是每个商城都有的功能,也是整个商城系统最重要的部分,购物车的做法有很多种,一般存放在本地缓存和数据库中比较常见,本文就是存放到了数据库中;
先放一张效果图:
先分析下要实现的功能:
1.数量的加减
2.单选、多选、全选
3.根据选中商品单价和数量计算金额
wxml:
<block wx:if='{{hasList}}'>
<!-- <>购物车列表 -->
<view class="carts-list">
<view wx:for="{{carts}}" class="carts-item" wx:key='cart' wx:item='item'>
<!-- //复选框 -->
<view class="carts-radio">
<image class="carts-select" bindtap="bindCheckbox" data-index="{{index}}" src="{{item.isSelect?'/img/icon/select.png':'/img/icon/n_select.png'}}" />
</view>
<!-- //商品信息 -->
<view class="carts-cnt">
<image class="carts-image" src="{{imghref}}{{item.goods_img}}" mode="aspectFill" />
<view class="carts-info">
<view class="carts-title clamp2">{{item.goods_name}}</view>
<text class="carts-guige">{{item.guige}}ml</text>
<view class="carts-subtitle">
<text class="carts-price c--f60">¥{{item.price}}</text>
</view>
</view>
</view>
<!-- //数量加减 -->
<view class="carts-num">
<text class="minus" bindtap="bindMinus" data-index='{{index}}'>-</text>
<input type="number" bindinput="bindIptCartNum" data-index='{{index}}' value="{{item.num}}" />
<text class="plus normal" data-index='{{index}}' bindtap="bindPlus">+</text>
</view>
<!-- //删除 -->
<icon class="carts-del" type="clear" size="16" color="#ccc" data-index="{{index}}" bindtap="bindCartsDel" />
</view>
</view>
<view class="carts-footer">
<view class="bottomfixed">
<view class="inner">
<view class="chkAll" bindtap="bindSelectAll">
<image class="allselect" src="{{selectAllStatus?'/img/icon/select.png':'/img/icon/n_select.png'}}" />
<text>全选</text>
</view>
<view class="total">合计:<em>¥{{totalMoney}}</em></view>
<view wx:if="{{totalCount != 0}}" class="btn-pay" bindtap='bindjiesuan'>去结算({{totalCount}})</view>
<view wx:else class="btn-pay disabled">去结算({{totalCount}})</view>
</view>
</view>
</view>
</block>
<block wx:else>
<view class="content" >
<view style="margin-top:50px;width:100%;">
<view style='font-size:15px;'>购物车没有商品!</view>
</view>
</view>
</block>
hasList 用于判断购物车中是否有数据
<!-- //复选框 -->
<view class="carts-radio">
<image class="carts-select" bindtap="bindCheckbox" data-index="{{index}}" src="{{item.isSelect?'/img/icon/select.png':'/img/icon/n_select.png'}}" />
</view>
这里的选择框我用了两个图片代替,一个是选中状态的图片,一个是非选中状态的图片,需要的话可以自行到iconfont去下载
wxss:
.c--f60{color: #f60;}
.clamp1, .clamp2, .clamp3{display: -webkit-box!important; overflow: hidden; -webkit-box-orient: vertical;}
.clamp1{-webkit-line-clamp:1;}
.clamp2{-webkit-line-clamp:2;}
.clamp3{-webkit-line-clamp:3;}
.carts-list{
padding: 0 20rpx;
}
.carts-list .carts-item{
border-top: 1rpx solid #e3e3e3;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 10rpx;
width: 100%;
position: relative;
}
.carts-list .carts-item:nth-child(1){
border-top: 0;
}
.carts-select{
margin-top:5px;
width:30px;
height:30px;
}
.carts-item .carts-cnt{
flex: 1;
padding: 0 20rpx;
}
.carts-cnt .carts-image{
float:left;
margin-right: 20rpx;
height: 150rpx;
width: 150rpx;
}
.carts-cnt .carts-info{
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 150rpx;
}
.carts-cnt .carts-title{
font-size:15px;
}
.carts-cnt .carts-guige{
font-size: 12px;
}
.carts-cnt .carts-subtitle{
display: flex;
flex-direction: row;
font-size: 15px;
}
.carts-list .carts-item .carts-del{
position: absolute;
top: 20rpx;
right: 10rpx;
}
/*数量加减*/
.carts-num{
border: 1rpx solid #aaa;
border-radius: 5rpx;
display: flex;
align-items: center;
align-self: flex-end;
text-align: center;
height: 50rpx;
}
.carts-num input{
border-left: 1rpx solid #aaa;
border-right: 1rpx solid #aaa;
font-size: 30rpx;
font-family: arial;
height: 50rpx;
line-height: 50rpx;
width: 80rpx;
}
.carts-num .minus, .carts-num .plus{color: #000; text-align: center; line-height: 50rpx; width: 40rpx;}
.carts-num .minus{font-size: 30rpx;}
.carts-num .minus.disabled{color: #ccc;}
.carts-num .plus{font-size: 34rpx;}
.bottomfixed{
position: fixed;
display: flex;
flex-direction: column;
bottom: 0;
width: 100%;
height: 120rpx;
line-height: 120rpx;
background: #f5f5f5;
}
.bottomfixed .inner{
display: flex;
flex-direction: row;
align-items: center;
}
.bottomfixed .inner .chkAll {
font-size: 28rpx;
margin-right: 40rpx;
margin-left: 20rpx;
display: flex;
flex-direction: row;
align-items: center;
}
.bottomfixed .inner .chkAll .allselect{
width:30px;
height:30px;
}
.bottomfixed .inner .total{
font-size:28rpx;
}
.bottomfixed .inner .total em{color:#f60;}
.btn-pay{
position: absolute;
right:0px;
background:#FF5E3A;
color:#fff;
padding:0 10px;
font-size: 28rpx;
}
.disabled{
background:#ccc;
}
.content{
width: 100%;
height:100%;
position: absolute;
left: 0;
font-size: 15px;
color:#999;
text-align:center;
}
js:
Page({
/**
* 页面的初始数据
*/
data: {
hasList: true,//购物车是否有数据
totalMoney: 0,//总金额
selectAllStatus: false,//是否全选
uid: 0, //用户ID
totalCount: 0,//数量
carts: [],
},
//设置文本框值
bindIptCartNum: function (e) {
const index = e.currentTarget.dataset.index;
var num = e.detail.value;
let carts = this.data.carts;
carts[index].num = num;
this.setData({
carts: carts
});
},
/* 点击减号 */
bindMinus: function (e) {
const index = e.currentTarget.dataset.index;
let carts = this.data.carts;
let num = carts[index].num;
if (num <= 1) {
return false;
}
num = num - 1;
carts[index].num = num;
this.setData({
carts: carts
});
this.getTotalPrice();
},
/* 点击加号 */
bindPlus: function (e) {
const index = e.currentTarget.dataset.index;
let carts = this.data.carts;
let num = carts[index].num;
num = num + 1;
carts[index].num = num;
this.setData({
carts: carts
});
this.getTotalPrice();
},
//删除商品
bindCartsDel(e) {
var that = this;
wx.showModal({
title: '提示',
content: '您确定要删除吗?',
success: function (res) {
if (res.confirm) {
//网络请求删除购物车数据
}
}
})
},
//计算总价
getTotalPrice() {
let carts = this.data.carts; // 获取购物车列表
let total = 0;
let num = 0;
for (let i = 0; i < carts.length; i++) { // 循环列表得到每个数据
if (carts[i].isSelect) { // 判断选中才会计算价格
total += carts[i].num * carts[i].price; // 所有价格加起来
num += carts[i].num;
}
}
this.setData({ // 最后赋值到data中渲染到页面
carts: carts,
totalCount: num,
totalMoney: total.toFixed(2)
});
},
//绑定单选
bindCheckbox: function (e) {
var that = this;
const idx = e.currentTarget.dataset.index;
let carts = that.data.carts;
const isSelect1 = carts[idx].isSelect;
carts[idx].isSelect = !isSelect1;
that.setData({
carts: carts,
selectAllStatus: false
});
that.getTotalPrice();
},
//绑定多选
bindSelectAll: function (e) {
var that = this;
let selectedAllStatus = that.data.selectAllStatus;
let carts = that.data.carts;
selectedAllStatus = !selectedAllStatus;
for (var i = 0; i < carts.length; i++) {
carts[i].isSelect = selectedAllStatus;
}
that.setData({
carts: carts,
selectAllStatus: selectedAllStatus
});
that.getTotalPrice();
},
//购物车结算
bindjiesuan: function () {
var that = this;
let carts = that.data.carts;
let jscart = [];
var j = 0
for (var i = 0; i < carts.length; i++) {
if (carts[i].isSelect) {
jscart[j] = carts[i];
j++;
}
}
if (jscart.length <= 0) {
wx.showToast({
title: '未选择商品',
icon: 'success',
duration: 1000
})
return;
}
wx.setStorageSync('jscart', jscart);//存入缓存
//转到结算页面
wx.navigateTo({
url: 'jiesuan?amount=' + that.data.totalMoney
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
//加载购物车
getCart: function () {
var that = this;
var uid = that.data.uid;
//网络请求获取购物车数据
}
})
微信赞赏:
上一篇: 嵌入式Linux下ntp移植
下一篇: 将gradle项目转换成maven项目