微信小程序-购物车功能

一个简单微信小程序购物车功能
首先感谢王慧永分享的文章,我直接将其中滑动的事件代码直接copy过来的。http://blog.csdn.net/u011072139/article/details/54692237

购物车展示

通过微信小程序方法
var datas = wx.getStorageSync("cars");
wx.setStorageSync("cars", JSON.stringify(datas));
保存读取数据,
item界面使使用position: absolute;和z-index: 4;实现
下面就直接贴代码了
布局:

<!--pages/sideslipDel/sideslipDel.wxml-->
<view class='container0'>

  <view wx:if='{{shoppingcars.length>0}}'>
    <view class='content_top'>
      <text class='content_top_txt_1'>购物车</text>
    </view>

    <view class='content_carts'>
      <block wx:for="{{shoppingcars}}" wx:for-index="idx" wx:for-item="item" wx:key="key">
        <view class='shoppingcaritem'>

          <view class='itemContent' bindtap='changeStatus' bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE" data-index='{{idx}}' style="{{item.value.txtStyle}}">
            <view class='car_icon'>
              <icon type='success' color='#d5242a' size='23' wx:if='{{item.value.isChecked}}'></icon>
              <icon type='circle' color='#d5242a' size='23' wx:else></icon>
            </view>

            <view class='image'>
              <image src='{{item.value.images}}' mode='widthFix'></image>
            </view>
            <view class='detailmess'>
              <view class='text0'>
                <text>{{item.value.name}}</text>
              </view>

              <view class='text2'>
                <view class='text2-'>
                  <text class='text2-0'>单价¥</text>
                  <text class='text2-1'>{{item.value.price}}</text>
                  <text class='text2-2'>/{{item.value.unit}}</text>

                </view>
              </view>

              <view class='add_sub_item'>

                <view class='add_sub'>
                  <image src='../../images/image_sub.png' mode='aspectFit' catchtap='btnSub' data-index='{{idx}}' />
                  <view class='add_sub_txt'>

                    <text>{{item.value.count}}</text>

                  </view>
                  <image src='../../images/image_add.png' mode='aspectFit' catchtap='btnAdd' data-index='{{idx}}' />
                </view>
              </view>

            </view>

          </view>

          <view class='itemDel'>
            <view bindtap="delItem" class="delItem" data-index='{{idx}}'>删除</view>
          </view>

        </view>
      </block>

    </view>

  </view>


</view>

样式:

/* pages/sideslipDel/sideslipDel.wxss */

.container0 {
  height: 100%;
  overflow-x: hidden;
  font-family: PingFangSC-Light, helvetica, 'Heiti SC';
}

/* **************goodsitem ***************************/

.content_top {
  border-bottom: #e5e5e5 solid 10rpx;
  width: 98%;
  height: 60rpx;
  line-height: 60rpx;
  margin-right: auto;
  margin-left: auto;
  vertical-align: middle;
  font-size: 0.925rem;
}


.content_top_txt_1 {
  float: right;
}

.content_carts {
  position: relative;
  width: 100%;
  height: 100%;
  border-bottom: #e5e5e5 solid 10rpx;
  overflow: hidden;
}

.shoppingcaritem {
  margin-left: auto;
  margin-right: auto;
  background: white;
  width: 100%;
  height: 190rpx;
  /* border-radius: 10rpx; */
  text-align: center;
  border-bottom: #e5e5e5 solid 2rpx;
  position: relative;
  overflow: hidden;
}

.itemContent {
  width: 100%;
  position: absolute;
  top: 0;
  background-color: #fff;
  z-index: 5;
  padding: 0 10rpx;
  transition: left 0.2s ease-in-out;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border:#7cba23 solid thin;
}

.itemDel {
  position: absolute;
  background-color: #e64340;
  height: 190%;
  width: 180rpx;
  line-height: 190rpx;
  vertical-align: middle;
  text-align: center;
  z-index: 4;
  top: 0;
  right: 0;
  color: #fff;
}

.car_icon {
  width: 10%;
  height: 180rpx;
  line-height: 180rpx;
  vertical-align: top;
  display: inline-block;
}

.car_icon icon {
  margin-right: 20rpx;
}

.shoppingcaritem .image {
  width: 170rpx;
  display: inline-block;
  height: 170rpx;
  margin-bottom: 10rpx;
  margin-top: 10rpx;
  padding-left: 5rpx;
  padding-right: 5rpx;

}

.image image {
  width: 100%;
  display: inline-block;
}

.detailmess {
  padding-left: 10rpx;
  width: 60%;
  height: 100%;
  float: right;
  vertical-align: top;
}

.detailmess text {
  width: 100%;
  display: inline-block;
  text-align: left;
  font-size: 28rpx;
  color: #000;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.text0 text {
  width: 100%;
  display: inline-block;
  margin-top: 20rpx;
  font-size: 32rpx;
  color: #434342;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: middle;
  text-align: left;
  font-weight: 550;
}

.text2 {
  width: 100%;
  display: inline-block;
}

.text2- {
  float: left;
  padding-top: 10rpx;
  vertical-align: middle;
}

.text2 text {
  display: inline;
  font-size: 26rpx;
  color: #9d9d9d;
  text-align: left;
}

.text2 .text2-0 {
  color: #434342;
  font-weight: 550;
}

.text2  .text2-2 {
  color: #434342;
  font-weight: 550;
}

.text2 .text2-1 {
  color: #d5242a;
  font-size: 30rpx;
}

.text2  .text2-3 {
  margin-left: 10rpx;
  color: white;
  background-color: brown;
  font-size: 0.555rem;
}



.add_sub_top {
  border: gray solid 0.2rpx;
  font-size: 0.725rem;
  color: #a5a5a5;
  float: left;
  padding-left: 10rpx;
  padding-right: 10rpx;
  max-width: 50%;
  overflow-x: hidden;
}

.add_sub_top text {
  height: 50rpx;
  line-height: 50rpx;
  vertical-align: middle;
}

.add_sub {
  width: 200rpx;
  height: 50rpx;
  line-height: 50rpx;
  vertical-align: middle;
  float: right;
  text-align: center;
}

.add_sub_txt {
  height: 50rpx;
  line-height: 50rpx;
  vertical-align: top;
  display: inline-block;
  padding-left: 15rpx;
  padding-right: 15rpx;
}

.add_sub_txt text {
  font-size: 1.0rem;
}

.add_sub image {
  height: 40rpx;
  width: 40rpx;
  margin: 5rpx;
  display: inline-block;
  /* border: red solid thin; */
}

/* *******以上*******goodsitem ***************************/


代码逻辑部分


const util = require('../../utils/util.js');

Page({
  /**
   * 页面的初始数据
   */
  data: {
    shoppingcars: [],//购物车数据集合
    delBtnWidth: 180,//删除按钮宽度
    isItemClikeAble: true
  },

// 购物车中的item是否被选中-改变状态
  changeStatus: function (event) {
    console.log(this.data.isItemClikeAble);
    if (this.data.isItemClikeAble) {
      var that = this;
      var idx = event.currentTarget.dataset.index;
      if (that.data.shoppingcars[idx].value.isChecked) {
        that.data.shoppingcars[idx].value.isChecked = false;
      }
      else {
        that.data.shoppingcars[idx].value.isChecked = true;
      }
      this.setData({
        shoppingcars: that.data.shoppingcars
      });


    }
  },

// 加入购物车
  btnAdd: function (event) {
    var idx = event.currentTarget.dataset.index;
    var shoppingcar = this.data.shoppingcars[idx];
    console.log("btnAdd");
    console.log(shoppingcar);
    util.saveCarData1(shoppingcar, shoppingcar.value.count + 1);

    try {
      wx.getStorageSync("cars");
      this.setData({
        shoppingcars: JSON.parse(wx.getStorageSync("cars")),
      });
    } catch (e) {
      this.setData({
        shoppingcars: [],
      });
    }

  },
  //移除购物车
  btnSub: function (event) {
    var idx = event.currentTarget.dataset.index;
    var shoppingcar = this.data.shoppingcars[idx];
    console.log("btnSub");
    console.log(shoppingcar);
    util.saveCarData1(shoppingcar, shoppingcar.value.count - 1);

    try {
      wx.getStorageSync("cars");
      this.setData({
        shoppingcars: JSON.parse(wx.getStorageSync("cars")),
      });

    } catch (e) {
      this.setData({
        shoppingcars: [],
      });
    }
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   * 在这里,如果本地数据为空,就加入两天数据,方便查看
   */
  onShow: function () {
    let str = [{ "key": "41", "value": { "name": "小白兔", "id": 41, "isChecked": true, "images": "../../images/002.jpg", "price": 19.5, "unit": "斤", "count": 1 } }, { "key": "40", "value": { "name": "大白兔", "id": 40, "isChecked": true, "images": "../../images/003.jpg", "price": 31.5, "unit": "斤", "count": 1 } }];
    try {
      wx.getStorageSync("cars");
      this.setData({
        shoppingcars: JSON.parse(wx.getStorageSync("cars")),
      });

      if (this.data.shoppingcars.length == 0) {
        this.setData({
          shoppingcars: str,
        });
        wx.setStorageSync("cars", JSON.stringify(str));
      }
    } catch (e) {
      this.setData({
        shoppingcars: str,
      });
      wx.setStorageSync("cars", JSON.stringify(str));
    }
    // }
    initdata(this);
    console.log(this.data.shoppingcars);
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },

  /**
   * bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE"
   * 分别是按下》》移动》》抬起事件
   */
  touchS: function (e) {
    console.log(e.touches[0].clientX);
    if (e.touches.length == 1) {
      this.setData({
        //设置触摸起始点水平方向位置  
        startX: e.touches[0].clientX
      });
    }
  },
  touchM: function (e) {
    var that = this
    initdata(that)
    if (e.touches.length == 1) {
      //手指移动时水平方向位置  
      var moveX = e.touches[0].clientX;
      //手指起始点位置与移动期间的差值  
      var disX = this.data.startX - moveX;
      console.log(disX);
      var delBtnWidth = this.data.delBtnWidth;
      var txtStyle = "";
      if (disX == 0 || disX < 0) {//如果移动距离小于等于0,文本层位置不变  
        txtStyle = "left:0rpx";
      } else if (disX > 0) {//移动距离大于0,文本层left值等于手指移动距离  
        txtStyle = "left:-" + disX + "rpx";
        if (disX >= delBtnWidth) {
          //控制手指移动距离最大值为删除按钮的宽度  
          txtStyle = "left:-" + delBtnWidth + "rpx";
        }
      }
      //获取手指触摸的是哪一项  
      var index = e.currentTarget.dataset.index;
      var list = this.data.shoppingcars;
      console.log("list", list[index]);
      list[index].value.txtStyle = txtStyle;
      //更新列表的状态  
      this.setData({
        shoppingcars: list
      });
    }
  },

  touchE: function (e) {
    if (e.changedTouches.length == 1) {
      //手指移动结束后水平位置  
      var endX = e.changedTouches[0].clientX;
      //触摸开始与结束,手指移动的距离  
      var disX = this.data.startX - endX;
      var delBtnWidth = this.data.delBtnWidth;
      //如果距离小于删除按钮的1/2,不显示删除按钮  
      var txtStyle = disX > delBtnWidth / 2 ? "left:-" + delBtnWidth + "rpx" : "left:0rpx";
      //获取手指触摸的是哪一项  
      var index = e.currentTarget.dataset.index;
      var list = this.data.shoppingcars;

      if (list[index].value.txtStyle != undefined && list[index].value.txtStyle.indexOf("-") != -1) {
        this.setData({
          isItemClikeAble: false
        });
      } else {
        this.setData({
          isItemClikeAble: true
        });
      }

      console.log("index", index);
      console.log("list", list);
      list[index].value.txtStyle = txtStyle;
      //更新列表的状态  
      this.setData({
        shoppingcars: list
      });
    }
  },
  //获取元素自适应后的实际宽度  
  getEleWidth: function (w) {
    var real = 0;
    try {
      var res = wx.getSystemInfoSync().windowWidth;
      var scale = (750 / 2) / (w / 2);//以宽度750px设计稿做宽度的自适应  
      // console.log(scale);  
      real = Math.floor(res / scale);
      return real;
    } catch (e) {
      return false;
      // Do something when catch error  
    }
  },
  initEleWidth: function () {
    var delBtnWidth = this.getEleWidth(this.data.delBtnWidth);
    this.setData({
      delBtnWidth: delBtnWidth
    });
  },
  //点击删除按钮事件  
  delItem: function (e) {
    var that = this
    wx.showModal({
      title: '提示',
      content: '是否删除?',
      success: function (res) {
        if (res.confirm) {
          //获取列表中要删除项的下标  
          var index = e.currentTarget.dataset.index;
          var list = that.data.shoppingcars;
          //移除列表中下标为index的项  
          list.splice(index, 1);
          //更新本地存储的购物车数据
          console.log(index);
          console.log(list);
          wx.setStorageSync("cars", JSON.stringify(list));
          //更新列表的状态  
          that.setData({
            shoppingcars: list
          });
          // initdata(that);
        } else {
          initdata(that)
        }
      }
    })
  },

})

var initdata = function (that) {
  var list = that.data.shoppingcars
  for (var i = 0; i < list.length; i++) {
    list[i].value.txtStyle = ""
  }
  that.setData({ shoppingcars: list })
}

* util.saveCarData1()方法*

function saveCarData1(item, num) {
  if (num >= 0) {
    var key = item.key;
    var value = item.value;

    value.count = num;
    console.log(item);
    try {
      var datas = wx.getStorageSync("cars");
      console.log(datas);
      var jsonData = JSON.parse(datas);
      // 获取json数组中key的值为item.key的json对象
      var temp = jsonData.filter((p) => {
        return p.key == key;
      });
      if (num != 0) {
        if (temp.length == 1) {
          temp[0].value.count = num;
        } else {
          jsonData.push({ "key": key, "value": value });
        }
      } else {
        if (temp.length == 1) {
          temp[0].value.count = num;
          var index = jsonData.indexOf(temp[0]);
          jsonData.splice(index, 1)
        } else {
          // jsonData.push({ "key": key, "value": value });
        }
      }
      console.log(jsonData)
      wx.setStorageSync("cars", JSON.stringify(jsonData));
    } catch (e) {
      if (num != 0) {
        var datas = [{ "key": key, "value": value }];
        wx.setStorageSync("cars", JSON.stringify(datas));
      }
    }

  }
}

以上就是大致的全部代码了,有所不足的地方还请大家多多斧正!

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序实现购物车功能代码主要分为两部分:前端和后端。前端代码实现用户界面的展示和交互,后端代码实现数据存储和处理。 前端代码: 1. 在页面的 .json 文件中添加购物车数据和购物车总价的变量 ``` { "data": { "cartList": [], // 购物车数据 "cartTotalPrice": 0 // 购物车总价 } } ``` 2. 在页面的 .wxml 文件中渲染购物车数据 ``` <view wx:for="{{cartList}}" wx:key="index"> <view>{{item.name}}</view> <view>{{item.price}}</view> <view>{{item.count}}</view> <view>{{item.totalPrice}}</view> </view> ``` 3. 绑定加入购物车事件,将商品数据添加到购物车数据中,并计算购物车总价 ``` onAddCart: function(event) { const item = event.currentTarget.dataset.item; let cartList = this.data.cartList; let index = cartList.findIndex(i => i.id === item.id); if (index === -1) { cartList.push({ id: item.id, name: item.name, price: item.price, count: 1, totalPrice: item.price }); } else { let count = cartList[index].count + 1; let totalPrice = count * item.price; cartList[index] = { ...cartList[index], count, totalPrice }; } let cartTotalPrice = cartList.reduce((total, i) => total + i.totalPrice, 0); this.setData({ cartList, cartTotalPrice }); } ``` 4. 绑定移除购物车事件,将商品数据从购物车数据中删除,并计算购物车总价 ``` onRemoveCart: function(event) { const item = event.currentTarget.dataset.item; let cartList = this.data.cartList; let index = cartList.findIndex(i => i.id === item.id); if (index !== -1) { cartList.splice(index, 1); } let cartTotalPrice = cartList.reduce((total, i) => total + i.totalPrice, 0); this.setData({ cartList, cartTotalPrice }); } ``` 后端代码: 1. 创建一个云数据库集合 cart,用于存储购物车数据 2. 在云函数中编写添加购物车数据的函数 ``` const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database() exports.main = async (event, context) => { const { id, name, price } = event try { const res = await db.collection('cart').where({ id }).get() if (res.data.length > 0) { const count = res.data[0].count + 1 const totalPrice = count * price await db.collection('cart').doc(res.data[0]._id).update({ data: { count, totalPrice } }) } else { const count = 1 const totalPrice = price await db.collection('cart').add({ data: { id, name, price, count, totalPrice } }) } return { success: true } } catch (err) { return { success: false, errMsg: err.message } } } ``` 3. 在云函数中编写获取购物车数据的函数 ``` const cloud = require('wx-server-sdk') cloud.init() const db = cloud.database() exports.main = async (event, context) => { try { const res = await db.collection('cart').get() return { success: true, data: res.data } } catch (err) { return { success: false, errMsg: err.message } } } ``` 4. 在页面的 .js 文件中调用云函数,实现前端与后端的数据交互 ``` onAddCart: function(event) { const item = event.currentTarget.dataset.item; wx.cloud.callFunction({ name: 'add-to-cart', data: item, success: res => { console.log(res); this.getCartList(); }, fail: err => { console.log(err); } }); }, getCartList: function() { wx.cloud.callFunction({ name: 'get-cart-list', success: res => { console.log(res); let cartList = res.result.data; let cartTotalPrice = cartList.reduce((total, i) => total + i.totalPrice, 0); this.setData({ cartList, cartTotalPrice }); }, fail: err => { console.log(err); } }); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值