首先我们在进入小程序后,肯定是通过用户授权并获取到用户的openID的,或者说至少有那么一个用户信息字段(比如在数据库中的用户表里,有openID、ID等)是跟购物车挂钩的,否则怎么能知道是我的购物车里有什么宝贝呢?在这里我是将用户表中的ID字段返回作为用户的唯一标识存储在globalData.userInfo中的。
在用户将商品添加到购物车后,数据库中的购物车表(cart表)主要存储了三个信息,一是商品ID(pid)、用户ID(uid)、购买数量(num),当然还有其他字段,比如商品规格(specs)、添加时间(addtime)、是否选中(selected,默认全为false)等等。
注意:是否选中在对购物车里的商品进行删除操作时会用到,比如选中多个商品进行删除,选中为true,然后将选中的id值存入数组传递给后台进行单个或者批量删除处理。
首先在util.js定义了一个函数,作用是在每次对购物车进行操作时(比如将商品添加到购物车、对购物车里的商品进行删除操作)都将购物车的数据存入到缓存carts中。
const promise = require('./promisify.js')
//util.js中原有的其他代码就省略了
const statsCart =(uid,cb) =>{
promise('request','GET',{
url:config.api['cart']+'/', //这里是接口地址,可修改为自己的
data:{
uid:uid //用户uid
}
}).then(function(res){
wx.setStorageSync('carts', res.data)
//这里为什么要将res.data数据返回,是因为在商品详细页中要用到,在很多商城类小程序中,在商品详情页中也有一个购物车图标,也能即时显示购物车中的商品数量,用回调的方式可以解决异步,否则不能够及时显示出来数量
typeof cb=='function'&&cb(res.data)
})
}
//将statsCart暴露出去
module.exports = {
statsCart:statsCart
}
上面代码中的promise是我封装的一个函数,适应于微信小程序中wx.request等api,文件名是promisify.js,与util.js存在于同一个目录utils
const promisify = (method, type = 'GET', options = {}) => {
return new Promise((resolve, reject) => {
options.success = res => {
resolve(res)
}
options.fail = err => {
reject(err)
}
if (type == 'POST') {
Object.assign(options, { method: type }, {
header: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
}
wx[method](options)
})
}
module.exports = promisify
在商品详情页中,用户点击添加到购物车按钮时,触发bindtap='addCartBtn'
//引入utils(util.js)和promise(promisify.js)两个文件
//添加到购物车
addCartBtn:function(){
let that = this
//在这里只给出添加到购物车关键代码,省略了选择验证及其他代码
promise('request','POST',{
url: utils.config.api['cart']+'/addcart', //添加到购物车后台接口地址,自行修改
data:{
pid:that.data.goodsInfo.id,//商品id
uid:app.globalData.userInfo.id, //用户id
num:that.data.num, //商品数量
selectName:that.data.selectName //商品规格
}
}).then(function(res){
//后台返回一个状态码表示添加成功
if(res.data.status){
promise('showToast','GET',{title:'添加成功'}).then(function(){
//在这里添加成功后,调用statsCart函数,即已将购物车信息存入缓存carts中,并且将返回的数量值绑定到cartsnum,cartsnum是商品详情页中购物车图标右上角显示的购物车商品数量,如下图所示。
utils.statsCart(app.globalData.userInfo.id,function(carts){
let cartnum=0
for(let i=0;i
在购物车页面,对商品进行操作的选项,比如删除购物车中的商品、清空购物车等。
购物车cart/cart.js主要代码,首先是要加载购物车里的数据。
//引入utils(util.js)和promise(promisify.js)两个文件
//为什么要在onShow中加载而不是在onLoad中,从生命周期而言,onLoad只加载一次,对于频繁操作购物车来说,数据是经常变更的。
onShow: function () {
promise('showLoading','GET',{title:'加载中'})
let that = this
that.loadInitData(that)
promise('hideLoading')
},
//加载数据
loadInitData:function(that){
let maxNum = []
utils.statsCart(app.globalData.userInfo.id,function(carts){
//因为有库存和限购的设置,在购物里有变更数量的操作,在这里可以忽略掉for循环和maxNum绑定,不属于此次功能实现的范围。
for (let i = 0; i < carts.length; i++) {
if (carts[i].limit) {
maxNum.push(carts[i].limit)
} else {
maxNum.push(carts[i].stock)
}
}
that.setData({
carts: carts,//绑定购物车数据
maxNum: maxNum
})
})
},
删除购物车里面的宝贝
//删除购物车里面的宝贝
deleteCart:function(){
let that = this
promise('showModal', 'GET', {
title: '提示',
content: '你确定要删除所选宝贝吗?',
cancelText: '我再想想',
cancelColor: '#CCCCCC',
confirmColor:'#FE5723',
}).then(function (res) {
if (res.confirm) {
let carts = that.data.carts //绑定的购物车列表数组
//下面的for循环是将已选中的商品id循环存入到新数组cartArr中
//因为在初始化数据时,已将购物车数据绑定到data的carts中,选中操作通过e.currentTarget.dataset.index下标对data.carts中selected取反变成true,再重新绑定进行更新data.carts中的数据
let cartArr = []
for(let i = 0; i
清空购物车
//清空购物车
clearCart:function(){
let that = this
promise('showModal','GET',{
title:'提示',
content:'你确定要清空购物车吗?',
cancelText:'我再想想',
cancelColor: '#CCCCCC',
confirmColor: '#FE5723'
}).then(function(res){
if(res.confirm){
promise('request','GET',{
url:utils.config.api['cart']+'/clearcart',//清空购物车API地址,自行修改
data:{
uid:app.globalData.userInfo.id
}
}).then(function(res){
if(res.data.status==1){
promise('showToast', 'GET', {
title: '删除成功',
icon: 'none'
}).then(function(){
utils.statsCart(app.globalData.userInfo.id)//这个步骤无需返回值,相当于更新缓存中的carts
that.setData({
carts: [] //将绑定的data.carts设为空数组
})
})
}
})
};
})
},
上面无论是将商品添加到购物车,还是将购物车里的商品单个、多个删除或是直接清空购物车,我们都直接或间接调用了utils.statsCart函数更新了缓存中carts数据。然后我们就可以通过定时器和wx.setTabBarBadge来做tabBar中购物车小图标右上角的文本了。
在app.js定义scanCarts函数
//扫描购物车统计购物车的数量
scanCarts:function(){
let goodnum=0
let carts = wx.getStorageSync('carts') //获取缓存中carts信息
for(let i=0;i
在app.js中的onLaunch函数中设置一个定义器,间隔100毫秒执行一次,以便达到即时更新的目的。
that.getUserInfo(function(userInfo){
that.globalData.userInfo = userInfo
setInterval(function(){
that.scanCarts()
},100)
});