小程序关于购物车功能的实现总结

小程序关于购物车功能的实现总结

一、 要求:
1、 能添加购物车,要求不重复,若添加相同的商品,则数量上加1,
2、 给购物车添加复选框按钮,点击或取消复选框时,可自动计算总价,
3、 当在复选框选中的情况下,可点击增加或减少某商品的数量,并实时计算商品总价,
4、 可管理购物车,如删除操作。
效果图:
在这里插入图片描述

二、 解决思路
2.1、解决添加购物车,并不重复,当添加相同的商品时,商品数量加1.
建立储存购物车信息数组:shopCarStore,可储存本地,储存的本地的目的是,当在商品页面添加好商品后,可在“我的购物车”页面通过wx.getStore获得。因为本地储存只能全覆盖不能追加,故在储存通过追加再储存,
添加购物车代码:

// detail.wxml
    <button class='joinshop' bindtap='joinshop' style="position: fixed; bottom:0;">加入购物车</button>
    <button class='immedbuy' bindtap='immedbuy' style="position: fixed; bottom:0;">立即购买</button>
// detail.js
joinshop:function(){
    var that  = this;
    if (this.data.shopCarStore.length!=0){
      var isFind = false;
      for(var i=0;i<this.data.shopCarStore.length;i++){
        if (app.appGoodInfo.goodInfo.pro_id == this.data.shopCarStore[i].pro_id){
          this.data.shopCarStore[i].goodNumber = this.data.shopCarStore[i].goodNumber+1;
          isFind = true;
        }else{
          isFind = false;
          //点击加入购物车后,将app.appGoodInfo.goodInfo追加数组shopCarStore中
        }
      }
        if (isFind == false ) {
          this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
        }
    }else{
      this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
    }
    // 再将shopCarStore存储到本地
    wx.setStorage({
      key: 'shopCarStore',
      data: that.data.shopCarStore,
      success:function(e){
        wx.showToast({
          title: '已加入购物车',
          icon: 'success',
          duration: 1000
        })
      },
      fail: function () {
        wx.showToast({
          title: '添加失败',
          icon: 'none',
          duration: 1000
        })
      }
    })
  },

**实现思路:**添加购物车的实质是将光标所点击的商品的信息储存的本地shopCarStore[](可自命名),在购物车页面获得本地信息并显示,当添加相同第二件商品时,通过for循环那遍历数组寻找商品的唯一标记值pro_id,若找到,则将该行数储存数据中商品数量值+1,(有些很多细节需要注意,比如知道加入购物车,goodNumber就因该值为最少为1,所以默认的初值为1)
代码片段:

for(var i=0;i<this.data.shopCarStore.length;i++){
        if (app.appGoodInfo.goodInfo.pro_id == this.data.shopCarStore[i].pro_id){
          this.data.shopCarStore[i].goodNumber = this.data.shopCarStore[i].goodNumber+1;
          isFind = true;
        }else{
          console.log("没找到pro_id");
          isFind = false;
        }
      }
        if (isFind == false ) {
          this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
        }
    }else{
      this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
    }

添加变量isFind的目的是确认遍历结果,如果找到pro_id,isFind终值为true,反之为false,为false时就追加该数据到shopCarStore中。
虽然思路清楚,但在实际代码操作过程中有很多细节要注意,比如是否找到的判断,是不能放在for循环中,自己在写的过程中在这块走了很多弯路,如果放在里面会出现第二次添加没有在购物车中的数据时goodNubmer成倍增加的情况。第三次添加相同的数据时,本应该要的效果是goodNumber数值加1,不添加新数据,但是也能添加进去,而且goodNumber变为原来有两倍,归根结底是for循环第一次没找到时就添加数据,一旦添加成功,原本循环的条件(数组长度就会立即边长+1),本没有循环就会有第二次循环,这个一直让我很奇怪,这就导致第二次循环时,或发现找到了pro_id,原本的1就会变成2
错误的写法情况有一下两种:

    // 第一种错误写法
  var isFind = false;
      for(var i=0;i<this.data.shopCarStore.length;i++){
        if (app.appGoodInfo.goodInfo.pro_id == this.data.shopCarStore[i].pro_id){
          this.data.shopCarStore[i].goodNumber = this.data.shopCarStore[i].goodNumber+1;
          isFind = true;
        }else{
          console.log("没找到pro_id");
          isFind = false;

          //点击加入购物车后,将app.appGoodInfo.goodInfo追加数组shopCarStore中
        }
if (isFind == false ) {
          this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
        }
      }
	// 第二种错误写法,这种写法的错误结果和上述相同,      for(var i=0;i<this.data.shopCarStore.length;i++){
        if(app.appGoodInfo.goodInfo.pro_id== this.data.shopCarStore[i].pro_id){
          this.data.shopCarStore[i].goodNumber = this.data.shopCarStore[i].goodNumber+1;
        }else{
          this.data.shopCarStore.push(app.appGoodInfo.goodInfo);
        }
      }

总结了下:原因还是for循环的原因,不可能总是第一次循环就能找到pro_id,一定要for循环变量结束才能判断,如果找到就goodNumber+1,反之追加数据

2.2、给购物车添加复选框按钮,点击或取消复选框时,可自动计算总价。
这里利用了复选框的响应事件bindchange=“checkboxChange”,在相对应的事件中可console.log(e),获得所需要的数据,
该功能那实现的思路是:
A、将该商品的一些属性:pro_id(唯一标识),price(价格),goodNumber(该商品在购物车中的数量),添加到数组money[]中
B、添加依据是:利用check的属性value,若value不为空,表示用户选中了,则添加该数据,若value为空,表示没有没有选中,需要判断该数据是否在money数组中(money[]的作用计算用户选中的商品的总价钱),原因是用户可能先选中了,这样就添加进了数组中,然后又点击了取消选中,所以就不能将该数据添加进数组,要删除。
C、最后将money储存在本地,储存的作用是为后面在选中的情况下,用户点击增加或减少商品时实时计算价格做准备。
具体可参考如下shopCar.js代码

// shopCar.wxml
<scroll-view scroll-y="true" style="height:568px">
<checkbox-group  bindchange="checkboxChange"  id="{{item.pro_id}}" data-index="{{index}}" data-goodNumber="{{item.goodNumber}}" data-price="{{item.pro_price}}" data-isCheck="{{isChecked}}" wx:for="{{shopCarStore}}">
<view class='good'>
  <checkbox  value="{{item.pro_id}}"  class="choose"/>
  <view class='store'>
      <image  src='../../Image/store.png'></image>
      <text class="title">{{item.pro_name}}</text>
      <button catchtap='deleCollect' data-index="{{index}}">删除该收藏</button>
  </view>
  <view class='info'>
    <image src='{{item.pro_img}}'></image>
    <text class='desc'>{{item.pro_desc}}</text>
    <text class='location'>货源地>>{{item.pro_address}}</text>
    <text class='price'>¥{{item.pro_price}}</text>
  </view>
  <view class='number'>
    <image class='bigdes' src='../../Image/bigdes.png' bindtap="reduceNumber"  data-index="{{index}}" value="{{item.pro_price}}"></image>
    <text class='numtext'>{{item.goodNumber}}</text>
    <image src='../../Image/bigadd.png' class='bigadd' bindtap="addNumber" bin data-index="{{index}}" ></image>
  </view>
</view>
</checkbox-group>
<view class='total' style="position: fixed; bottom:0;">
  <view  class='total1'>
      <text>合计:¥{{totalMoney}}</text>
  </view>
  <view  class='topay'>
      <text>去结算</text>
  </view>
</view>
</scroll-view>

// shopCar.js
// 复选框响应事件
checkboxChange:function(e){
    console.log(e);
    var that = this;
    var pro_id = e.currentTarget.id;
    var checked = e.currentTarget.dataset.price;
    checked = true;
    if (e.detail.value!=''){
      this.data.info = { price: e.currentTarget.dataset.price, pro_id: e.currentTarget.id, goodNumber: e.currentTarget.dataset.goodnumber, isChecked: checked};
      this.data.money.push(this.data.info);
      wx.setStorage({
        key: 'money',
        data: this.data.money,
      })
    }else{
      this.data.isChecked = false;
        for(var i = 0;i<this.data.money.length;i++){
        if (pro_id == this.data.money[i].pro_id){
          this.removeById(this.data.money,i);
          wx.setStorage({
            key: 'money',
            data: this.data.money,
          })
        }
      }
    }
    this.sum();  // 调用了求和的方法
  },
// money求和运算 , 计算总价格
  sum:function(){
    var sum = 0;
    if (this.data.money.length!=0){
      for (var i = 0; i < this.data.money.length; i++) {
        sum = sum + (this.data.money[i].price)*(this.data.money[i].goodNumber);
      }
      this.setData({ totalMoney: sum });
    }else{
      this.setData({ totalMoney: 0 });
    }
  },

感悟总结:这块用了两种方法,第一种方法是走了不少弯路,原因是自己对value值的利用不得当,虽然最终也做出来了,效果没有上述的方便明了,哈哈哈。可能是为第二种方法铺路。
2.3、当在复选框选中的情况下,可点击增加或减少某商品的数量,并实时计算商品总价。
实现思路:首先点击按钮增加或减少的实质是通过index值,更改在本地储存购物车数据shopCatStore中index相对应的行数据中的goodNumber,并调用this.onShow实时显示,要注意的是:
A、 对更改的shopCarStorep[]数据要及时保存,不然即便调用onShow方法也会出错。
B、 调用onshow方法的前提是:onshow方法中有对应显示功能的代码,本处实际上就是从本地获得shopCarStore,并显示。
这里加了一个前提条件:“在复选框选中的情况下”,所以就要用到前面提到的存到本地数组money,实际上,一旦能添加到money中,就说明该数据已选中,只需更改money[]中的goodNumber值即可。需要注意的还是对money[]的实时保存
代码如下:
// 控制商品数的数量

  addNumber:function(e){
    console.log(e);
    var that = this;
    var index = e.currentTarget.dataset.index;
    (this.data.shopCarStore[index].goodNumber)++;
    wx.setStorage({
      key: 'shopCarStore',
      data: that.data.shopCarStore,
      success:function(){
        that.onShow();
        wx.getStorage({
          key: 'money',
          success: function (res) {
            that.setData({ money: res.data });
            for (var i = 0; i < that.data.money.length; i++) {
              if (that.data.shopCarStore[index].pro_id==that.data.money[i].pro_id) {
                (that.data.money[i].goodNumber)++ ; 
              }
            }
            that.sum();
            wx.setStorage({
              key: 'money',
              data: that.data.money,
            })
          },
        })
      }
    })
  },

// 减少商品时对应的方法

  reduceNumber:function(e){
    console.log(e);
    var that = this;
    var index = e.currentTarget.dataset.index;
    if (this.data.shopCarStore[index].goodNumber>1){
      (this.data.shopCarStore[index].goodNumber)--;
    }else{
      this.data.shopCarStore[index].goodNumber = 1;
    }
    wx.setStorage({
      key: 'shopCarStore',
      data: that.data.shopCarStore,
      success: function () {
        that.onShow(); 
        wx.getStorage({
          key: 'money',
          success: function (res) {
            that.setData({ money: res.data });
            for (var i = 0; i < that.data.money.length; i++) {
              if (that.data.shopCarStore[index].pro_id == that.data.money[i].pro_id) {
                (that.data.money[i].goodNumber)--;
              }
            }
            that.sum();
            wx.setStorage({
              key: 'money',
              data: that.data.money,
            })
          },
        })
      }
    })
  },

2.4、可管理购物车,如删除操作。
实现思路:思路很简单,还是依据当前点击所在的index,寻找在shopCarStore对应的index ,并删除,删除借用了自定义方法removeById(),需要注意的还是对曹锁后的shopCarStore的实时保存,否则一旦涉及到shopCarStore的获取都不是最新数据。
代码如下:
// 删除收藏

  deleCollect:function(e){
    console.log(e);
    var index = e.currentTarget.dataset.index;
    var that = this;
    wx.showModal({
      title: '提示',
      content: '是否确认删除?',
      success: function (res) {
        if(res.confirm){
          console.log("用户点击了确认");
          wx.getStorage({
            key: 'shopCarStore',
            success: function (res) {
              that.setData({ temp_shopCarStore: res.data });
              // 根据点击的索引值删除数组中相对应的数据
              that.removeById(that.data.temp_shopCarStore, index);
              wx.setStorage({
                key: 'shopCarStore',
                data: that.data.temp_shopCarStore,
                success: function () {
                  wx.showToast({
                    title: '删除成功',
                    icon: "success",
                    duration: 2000
                  })
                  // 调用生命周期函数的目的是为了能让更新后的数据及时显示
                  that.onShow();
                }
              })
            },
          })     
        }else{
          console.log("用户点击了取消");
        }
      }
    })
  },
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值