在我的GitHub上有校园二手交易微信小程序的源码,这里面包含了购物车的功能,GitHub地址:https://github.com/zhuyuzhu/Secondhand-goods-on-campus,该项目的pages文件夹下的shoppingCart文件夹就是购物车的代码。
购物车功能实现的逻辑:
(1)从服务器拿到的物品数据data里面,只有物品的信息,我们需要给每个物品数据中加入一个是否选中的属性
这样当我们在点击选择按钮的时候,就可以选中该物品,当再次点击的时候,就可以取消选择。
其中几个主要的功能:
(1)物品请求数据,使用微信小程序request请求,POST方式得到服务器传来的物品数据。
每次请求要想后端传入用户id和物品id(物品id根据后端要求进行处理,我每次传入请求到的物品中最后一个物品的id,后端会把这个id之后的5个值再传给前端)才得到的物品数据,每一次请求要判断还有没有数据,有数据则请求成功,没有数据就不请求。
(2)选中和取消选中单个物品
(3)选中或取消选中物品时,总价格要进行加减
每次触发选择事件,都会触发计算总价的方法
(4)全选按钮,实现物品的全选
当用户通过单选选择了所有物品时,“全选按钮”会自动改变为选中样式;当用户通过“全选按钮”选择所有商品的时候,每个商品都应该是选中状态。
(5)计算总价
任何一次触发该函数,都会重新计算价格,将总价变为0,再进行选中项的价格累加,而不是在原总价上累加或减某一个商品的价格
wxml代码:
书本
物品
×
没有书本啦~_~
×
没有物品啦~_~
全选
合计:
¥{{totalPrice}}
wxss代码:
/* pages/shoppingCart/shoppingCart.wxss */
.wrapper {
position: fixed;
top: 0rpx;
display: flex;
width: 100%;
height: 50rpx;
justify-content: space-around;
background-color: #fff;
z-index: 9999;
}
.select {
text-align: center;
width: 50%;
background-color: green;
color: #fff;
}
.noSelect {
width: 50%;
text-align: center;
}
.cart-box {
margin-top: 50rpx;
margin-bottom: 100rpx;
}
.cart-goods {
display: flex;
flex-direction: row;
padding: 30rpx;
border-bottom: 3rpx solid #e6e6e6;
}
.icon-wrapper {
line-height: 260rpx;
}
.cart-icon {
display: inline-block;
margin: auto 10rpx;
margin-left: -10rpx;
}
.cart-img {
display: flex;
width: 580rpx;
height: 260rpx;
}
.cart-img image{
margin: auto 0rpx;
width: 165rpx;
height: 225rpx;
}
.cart-goods .cart-message {
width: 380rpx;
display: flex;
flex-direction: column;
margin: 0 20rpx;
justify-content: space-around;
}
.name{
font-weight: 600;
color: #4a4a4a;
font-size: 32rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.author,
.press{
font-size: 28rpx;
color: #9e9e9e;
font-weight: 300;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.price {
font-size: 28rpx;
color: #f40;
font-weight: 300;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.delete {
position: absolute;
right: 40rpx;
margin-top: -10rpx;
}
.cart-bottom {
position: fixed;
width: 100%;
height: 100rpx;
background-color: white;
bottom: 0rpx;
}
.cart-allPrice {
float:left;
padding: 0.5rem;
font-weight: 100;
margin-left: 70rpx;
}
.allPrice {
float:left;
padding: 0.5rem;
font-weight: 100;
margin-left: -30rpx;
color: #f40;
}
.cart-allSelect {
float:left;
padding: 0.5rem;
margin-left: -23rpx;
font-weight: 100
}
.cart-iconAll {
float:left;
padding: 0.5rem;
margin-top: 7rpx;
}
.btn-red {
background-color: #f44336; /* 红色 */
font-size: 40rpx;
}
button {
position: fixed;
right: 0;
color: white;
text-align: center;
display: inline-block;
font-size: 30rpx;
border-radius: 0rpx;
width: 30%;
height: 100rpx;
line-height: 100rpx;
}
.cart-list {
display: flex;
flex-direction: column;
}
.bottom {
color: #666;
text-align: center;
font-size: 30rpx;
}
微信js代码:
// pages/shoppingCart/shoppingCart.js
var app = getApp();
const orginalPrice = 0; //由于0.00在赋值时是0,用toFixed()取余
Page({
/**
* 页面的初始数据
*/
data: {
selectTab: true,
selectBook: true,
selectThing: false,
carts: [], // 购物车列表
hasList: false, // 列表是否有数据
totalPrice: orginalPrice.toFixed(2), // 总价,初始为0
selectAllStatus: false, // 全选状态,默认全选
bookId: '',
isMyCartShow: false,
studentId: '',
myCartBookLength: '5',
bookPrice: 0,
thingId: '',
thingCarts: [], // 物品列表
isThingCartShow: false,
myCartThingLength: '5',
thingPrice: 0,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
var that = this;
var studentId = that.data.studentId;
var hasList = that.data.hasList;
try {
var value = wx.getStorageSync('studentIdSync')
if (value) {
console.log(value); //同步得到studentId的值
that.setData({
studentId: value
})
}
} catch (e) {
console.log(0);
}
this.getBookCartList()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
// 动态设置导航条标题
wx.setNavigationBarTitle({
title: '购物车'
});
wx.showNavigationBarLoading(); //在标题栏中显示加载图标
setTimeout(function(){
wx.stopPullDownRefresh(); //停止加载
wx.hideNavigationBarLoading(); //隐藏加载icon
},2000)
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
if (this.data.selectBook){
this.getBookCartList()
}else {
this.getThingCartList()
}
},
getBookCartList(){
console.log(1);
var that = this;
var url = app.globalData.huanbaoBase + 'getbooksbystudentid.php'
var ismyCartShow = that.data.ismyCartShow;
var carts = that.data.carts;
var bookId = that.data.bookId;
var myCartBookLength = that.data.myCartBookLength;
var studentId = that.data.studentId;
console.log(bookId, myCartBookLength);
// if (myCartBookLength < 5) {
// that.setData({
// isMyCartShow: true
// })
// return
// }
wx.showToast({
title: '加载中',
icon: 'loading',
duration: 1000,
})
wx.request({
url,
method: 'POST',
header: { 'content-type': 'application/x-www-form-urlencoded ' },
data: { //此处设置,一定要与后台一一对应,属性名和属性的先后位置。
studentId: studentId,
lastId: bookId,
},
success: res => {
var carts = that.data.carts || [];
var data = res.data.data;
console.log(data);
if(data === undefined) {
wx.hideToast()
that.setData({
isMyCartShow: true
})
return
}
that.setData({
myCartBookLength: data.length //每次获取5组值
})
myCartBookLength = data.length;
that.setData({
bookId: res.data.data[myCartBookLength - 1].bookid
})
console.log(myCartBookLength);
data.forEach(item => {
let messege = {
selected: false,
...item
}
carts.push(messege); //实现购物车的最近添加的物品,展现在最前面
})
that.setData({
carts: carts ,
})
},
fail: err => {
console.log(err);
}
})
},
getThingCartList() {
console.log(1);
var that = this;
var url = app.globalData.huanbaoBase + 'getthingsbystudentid.php'
var isThingCartShow = that.data.isThingCartShow;
var thingCarts = that.data.thingCarts;
var thingId = that.data.thingId;
var myCartThingLength = that.data.myCartThingLength;
var studentId = that.data.studentId;
var selectBook = that.data.selectBook;
var selectThing = that.data.selectThing;
console.log(thingId, myCartThingLength);
// if (myCartThingLength < 5) {
// that.setData({
// isThingCartShow: true
// })
// return
// }
wx.showToast({
title: '加载中',
icon: 'loading',
duration: 1000,
})
wx.request({
url,
method: 'POST',
header: { 'content-type': 'application/x-www-form-urlencoded ' },
data: { //此处设置,一定要与后台一一对应,属性名和属性的先后位置。
studentId: studentId,
lastId: thingId,
},
success: res => {
var thingCarts = that.data.thingCarts || [];
var data = res.data.data;
console.log(data);
if (data === undefined) {
wx.hideToast()
that.setData({
isThingCartShow: true
})
return
}
that.setData({
myCartThingLength: data.length //每次获取5组值
})
myCartThingLength = data.length;
that.setData({
thingId: res.data.data[myCartThingLength - 1].goodid
})
console.log(myCartThingLength);
data.forEach(item => {
let messege = {
selected: false,
...item
}
thingCarts.push(messege); //实现购物车的最近添加的物品,展现在最前面
})
that.setData({
thingCarts: thingCarts,
})
},
fail: err => {
console.log(err);
}
})
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
//计量总价
getTotalPrice() {
let carts = this.data.carts; // 获取购物车列表
let thingPrice = parseFloat(this.data.thingPrice);
let bookPrice = parseFloat(this.data.bookPrice);
let total = 0.00;
for (let i = 0; i < carts.length; i++) { // 循环列表得到每个数据
if (carts[i].selected) { // 判断选中才会计算价格
total += parseFloat(carts[i].bprice); // 所有价格加起来
}
}
this.setData({
bookPrice: total.toFixed(2)
})
total += thingPrice;
this.setData({ // 最后赋值到data中渲染到页面
carts: carts,
totalPrice: total.toFixed(2) //保留小数后面2两位
});
},
//选择事件
selectList(e) {
let that = this;
const index = e.currentTarget.dataset.index; // 获取data- 传进来的index
console.log(index);
let selectAllStatus = that.data.selectAllStatus; //是否已经全选
let str = true; //用str与每一项进行状态判断
let carts = that.data.carts; // 获取购物车列表
const selected = carts[index].selected; // 获取当前商品的选中状态
carts[index].selected = !selected; // 改变状态
that.setData({
carts: carts
});
that.getTotalPrice(); // 重新获取总价
for (var i = 0; i < carts.length; i++) {
str = str && carts[i].selected; //用str与每一项进行状态判断
}
if (str === true) {
that.setData({
selectAllStatus: true
})
} else {
that.setData({
selectAllStatus: false
})
}
},
//全选事件
selectAll(e) {
var that = this;
let selectAllStatus = that.data.selectAllStatus; // 是否全选状态
let carts = that.data.carts;
let thingCarts = that.data.thingCarts;
var selectThing = that.data.selectThing;
var selectBook = that.data.selectBook;
if(selectBook) {
selectAllStatus = !selectAllStatus;
for (let i = 0; i < carts.length; i++) {
carts[i].selected = selectAllStatus; // 改变所有商品状态
}
that.setData({
selectAllStatus: selectAllStatus,
carts: carts
});
that.getTotalPrice(); // 重新获取总价
if (carts.length === 0) { //当没有物品时,不能再点“全选”
wx.showModal({
title: '提示',
content: '购物车空空如也~',
success: function (res) { //模糊层成功出来后
if (res.confirm) {
console.log('用户点击确定')
that.setData({
selectAllStatus: false
})
} else {
console.log('用户点击取消')
that.setData({
selectAllStatus: false
})
}
},
})
}
}else {
selectAllStatus = !selectAllStatus;
for (let i = 0; i < thingCarts.length; i++) {
thingCarts[i].selected = selectAllStatus; // 改变所有商品状态
}
that.setData({
selectAllStatus: selectAllStatus,
thingCarts: thingCarts
});
that.getTotalPriceThing(); // 重新获取总价
if (thingCarts.length === 0) { //当没有物品时,不能再点“全选”
wx.showModal({
title: '提示',
content: '购物车空空如也~',
success: function (res) { //模糊层成功出来后
if (res.confirm) {
console.log('用户点击确定')
that.setData({
selectAllStatus: false
})
} else {
console.log('用户点击取消')
that.setData({
selectAllStatus: false
})
}
},
})
}
}
},
//删除商品
deleteList(e) {
const index = e.currentTarget.dataset.index;
var selectAllStatus = this.data.selectAllStatus;
let carts = this.data.carts;
let totalPrice = this.data.totalPrice;
wx.showModal({
title: '提示',
content: '将此产品移除购物车?',
success: res=> {
if (res.confirm) {
console.log('用户点击确定')
carts.splice(index, 1); // 删除购物车列表里这个商品
this.setData({
carts: carts
});
if (carts.length == 0) { // 如果购物车为空
this.setData({
hasList: false, // 修改标识为false,显示购物车为空页面
selectAllStatus: false,
totalPrice: orginalPrice.toFixed(2) //此时价格为0
});
} else { // 如果不为空
this.getTotalPrice(); // 重新计算总价格
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
// 物品
//计量总价
getTotalPriceThing() {
let thingCarts = this.data.thingCarts; // 获取购物车列表
let total = 0; //注意后台返回的是字符串数字。
let thingPrice = parseFloat(this.data.thingPrice);
let bookPrice = parseFloat(this.data.bookPrice);
for (let i = 0; i < thingCarts.length; i++) { // 循环列表得到每个数据
if (thingCarts[i].selected) { // 判断选中才会计算价格
total += parseFloat(thingCarts[i].gprice); // 所有价格加起来
}
}
this.setData({
thingPrice: total
})
total += bookPrice;
this.setData({ // 最后赋值到data中渲染到页面
thingCarts: thingCarts,
totalPrice: total.toFixed(2) //保留小数后面2两位
});
},
//选择事件
selectListThing(e) {
let that = this;
const index = e.currentTarget.dataset.index; // 获取data- 传进来的index
console.log(index);
let selectAllStatus = that.data.selectAllStatus; //是否已经全选
let str = true; //用str与每一项进行状态判断
let thingCarts = that.data.thingCarts; // 获取购物车列表
const selected = thingCarts[index].selected; // 获取当前商品的选中状态
thingCarts[index].selected = !selected; // 改变状态
that.setData({
thingCarts: thingCarts
});
that.getTotalPriceThing(); // 重新获取总价
for (var i = 0; i < thingCarts.length; i++) {
str = str && thingCarts[i].selected; //用str与每一项进行状态判断
}
console.log(str);
if (str === true) {
that.setData({
selectAllStatus: true
})
} else {
that.setData({
selectAllStatus: false
})
}
},
//删除商品
deleteListThing(e) {
const index = e.currentTarget.dataset.index;
var selectAllStatus = this.data.selectAllStatus
let thingCarts = this.data.thingCarts;
let totalPrice = this.data.totalPrice;
wx.showModal({
title: '提示',
content: '将此产品移除购物车?',
success: res=> {
if(res.confirm){
console.log("用户点了确定")
thingCarts.splice(index, 1); // 删除购物车列表里这个商品
this.setData({
thingCarts: thingCarts
});
if (thingCarts.length == 0) { // 如果购物车为空
this.setData({
hasList: false, // 修改标识为false,显示购物车为空页面
selectAllStatus: false,
totalPrice: orginalPrice.toFixed(2) //此时价格为0
});
} else { // 如果不为空
this.getTotalPrice(); // 重新计算总价格
}
}else if(res.cancel) {
console.log("用户点了取消")
}
}
})
},
chooseBookCart() {
var that = this;
var selectBook = that.data.selectBook;
var selectThing = that.data.selectThing;
let selectAllStatus = that.data.selectAllStatus; //是否已经全选
let str = true; //用str与每一项进行状态判断
let carts = that.data.carts;
for (var i = 0; i < carts.length; i++) {
str = str && carts[i].selected; //用str与每一项进行状态判断
}
console.log(str);
that.setData({
selectBook: true,
selectThing: false,
})
},
chooseThingCart() {
var that = this;
var selectThing = that.data.selectThing;
var selectBook = that.data.selectBook;
var selectAllStatus = that.data.selectAllStatus;
that.setData({
selectBook: false,
selectThing: true,
})
// 此时data中的数据改变,但是此时的属性值还未改变
that.getThingCartList()
},
toBuy(){
var totalPrice = this.data.totalPrice;
var thingCarts = this.data.thingCarts;
var bookCarts = this.data.carts;
var bookId = this.data.bookId;
var bookCart = [], thingCart = [];
bookCarts.forEach(item=>{
if (item.selected){
bookCart.push(item);
}
})
thingCarts.forEach(item=>{
if (item.selected){
thingCart.push(item);
}
})
let shoppingCartList = {thingCart, bookCart};
console.log(bookCart);
if(totalPrice === '0.00'){
console.log(totalPrice);
}else {
console.log(shoppingCartList);
wx.navigateTo({
url: '../settlement/settlement?bookCart='+bookCart,
})
}
}
})
后端代码和数据库有时间再写吧。。。