天天看點

微信小程式 在tabBar某一項的右上角添加文本(購物車數量)

首先我們在進入小程式後,肯定是通過使用者授權并擷取到使用者的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<carts.length;i++){
              cartnum+=carts[i].num
            }
            that.setData({
              cartsnum: cartnum
            })
          })
        })
      };
    })
  },
           
微信小程式 在tabBar某一項的右上角添加文本(購物車數量)

在購物車頁面,對商品進行操作的選項,比如删除購物車中的商品、清空購物車等。

購物車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<carts.length;i++){
          if(carts[i].selected==true){
            cartArr.push(carts[i].cid) //這個cid是購物車唯一辨別的自增id值
          }
        }
        promise('request','GET',{
          url:utils.config.api['cart']+'/deletecart',//删除購物車商品的API位址,自行修改
          data:{
            uid:app.globalData.userInfo.id,
            cartarr:cartArr.join() //選中的數組id,通過join()形成1,2,3的形式,背景SQL語句通過IN(1,2,3)進行操作
          }
        }).then(function(res){
          if(res.data.status==1){
            promise('showToast', 'GET', {
              title: '删除成功',
              icon: 'none'
            }).then(function(){
              that.loadInitData(that) //删除成功後再重新初始化資料
            })
          }
        })
      };
    })
  },
           

清空購物車

//清空購物車
  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<carts.length;i++){
      goodnum+=carts[i].num //通過for循環對數量進行累加
    }
    if(goodnum){ //如果數量存在,即不為0,添加徽章
      wx.setTabBarBadge({
        index: 2, //圖示下标是從0開始,2代表第3個圖示
        text: ''+goodnum+'',
      })
    }else{
      wx.removeTabBarBadge({ 
        index: 2, //否則移除徽章
      })
    }
  },
           

在app.js中的onLaunch函數中設定一個定義器,間隔100毫秒執行一次,以便達到即時更新的目的。

that.getUserInfo(function(userInfo){
  that.globalData.userInfo = userInfo
  setInterval(function(){
    that.scanCarts()
  },100)
});