精华

微信小程序之购物车功能

  • • 发表于 8年前
  • • 作者 淋星雨
  • • 8635 人浏览
  • • 13 条评论
  • • 最后编辑时间 8年前
  • • 来自 [技 术]
  • • 专栏  [小程序Demo项目]

原创声明:本文为作者原创,未经允许不得转载,经授权转载需注明作者和出处

前言

以往的购物车,基本都是通过大量的 DOM 操作来实现。微信小程序其实跟 vue.js 的用法非常像,接下来就看看小程序可以怎样实现购物车功能。

需求

image

先来弄清楚购物车的需求。

  • 单选、全选和取消,而且会随着选中的商品计算出总价
  • 单个商品购买数量的增加和减少
  • 删除商品。当购物车为空时,页面会变为空购物车的布局

根据设计图,我们可以先实现静态页面。接下来,再看看一个购物车需要什么样的数据。

  • 首先是一个商品列表(carts),列表里的单品需要:商品图(image),商品名(title),单价(price),数量(num),是否选中(selected),商品id(id)
  • 然后左下角的全选,需要一个字段(selectAllStatus)表示是否全选了
  • 右下角的总价(totalPrice)
  • 最后需要知道购物车是否为空(hasList)

知道了需要这些数据,在页面初始化的时候我们先定义好这些。

代码实现

初始化

  1. Page({
  2. data: {
  3. carts:[], // 购物车列表
  4. hasList:false, // 列表是否有数据
  5. totalPrice:0, // 总价,初始为0
  6. selectAllStatus:true // 全选状态,默认全选
  7. },
  8. onShow() {
  9. this.setData({
  10. hasList: true, // 既然有数据了,那设为true吧
  11. carts:[
  12. {id:1,title:'新鲜芹菜 半斤',image:'/image/s5.png',num:4,price:0.01,selected:true},
  13. {id:2,title:'素米 500g',image:'/image/s6.png',num:1,price:0.03,selected:true}
  14. ]
  15. });
  16. },
  17. })

购物车列表数据我们一般是通过请求服务器拿到的数据,所以我们放在生命周期函数里给 carts 赋值。想到每次进到购物车都要获取购物车的最新状态,而onLoad和onReady只在初始化的时候执行一次,所以我需要把请求放在 onShow 函数里。(这里先拿点假数据冒充一下吧)

布局 wxml

修好之前写好的静态页面,绑定数据。

  1. <view class="cart-box">
  2. <!-- wx:for 渲染购物车列表 -->
  3. <view wx:for="{{carts}}">
  4. <!-- wx:if 是否选择显示不同图标 -->
  5. <icon wx:if="{{item.selected}}" type="success" color="red" bindtap="selectList" data-index="{{index}}" />
  6. <icon wx:else type="circle" bindtap="selectList" data-index="{{index}}"/>
  7. <!-- 点击商品图片可跳转到商品详情 -->
  8. <navigator url="../details/details?id={{item.id}}">
  9. <image class="cart-thumb" src="{{item.image}}"></image>
  10. </navigator>
  11. <text>{{item.title}}</text>
  12. <text>¥{{item.price}}</text>
  13. <!-- 增加减少数量按钮 -->
  14. <view>
  15. <text bindtap="minusCount" data-index="{{index}}">-</text>
  16. <text>{{item.num}}</text>
  17. <text bindtap="addCount" data-index="{{index}}">+</text>
  18. </view>
  19. <!-- 删除按钮 -->
  20. <text bindtap="deleteList" data-index="{{index}}"> × </text>
  21. </view>
  22. </view>
  23. <!-- 底部操作栏 -->
  24. <view>
  25. <!-- wx:if 是否全选显示不同图标 -->
  26. <icon wx:if="{{selectAllStatus}}" type="success_circle" color="#fff" bindtap="selectAll"/>
  27. <icon wx:else type="circle" color="#fff" bindtap="selectAll"/>
  28. <text>全选</text>
  29. <!-- 总价 -->
  30. <text>¥{{totalPrice}}</text>
  31. </view>

计算总价

总价 = 选中的商品1的 价格 数量 + 选中的商品2的 价格 数量 + …
根据公式,可以得到

  1. getTotalPrice() {
  2. let carts = this.data.carts; // 获取购物车列表
  3. let total = 0;
  4. for(let i = 0; i<carts.length; i++) { // 循环列表得到每个数据
  5. if(carts[i].selected) { // 判断选中才会计算价格
  6. total += carts[i].num * carts[i].price; // 所有价格加起来
  7. }
  8. }
  9. this.setData({ // 最后赋值到data中渲染到页面
  10. carts: carts,
  11. totalPrice: total.toFixed(2)
  12. });
  13. }

页面中的其他操作会导致总价格变化的都需要调用该方法。

选择事件

点击时选中,再点击又变成没选中状态,其实就是改变 selected 字段。通过 data-index=”{{index}}” 把当前商品在列表数组中的下标传给事件。

  1. selectList(e) {
  2. const index = e.currentTarget.dataset.index; // 获取data- 传进来的index
  3. let carts = this.data.carts; // 获取购物车列表
  4. const selected = carts[index].selected; // 获取当前商品的选中状态
  5. carts[index].selected = !selected; // 改变状态
  6. this.setData({
  7. carts: carts
  8. });
  9. this.getTotalPrice(); // 重新获取总价
  10. }

全选事件

全选就是根据全选状态 selectAllStatus 去改变每个商品的 selected

  1. selectAll(e) {
  2. let selectAllStatus = this.data.selectAllStatus; // 是否全选状态
  3. selectAllStatus = !selectAllStatus;
  4. let carts = this.data.carts;
  5. for (let i = 0; i < carts.length; i++) {
  6. carts[i].selected = selectAllStatus; // 改变所有商品状态
  7. }
  8. this.setData({
  9. selectAllStatus: selectAllStatus,
  10. carts: carts
  11. });
  12. this.getTotalPrice(); // 重新获取总价
  13. }

增减数量

点击+号,num加1,点击-号,如果num > 1,则减1

  1. // 增加数量
  2. addCount(e) {
  3. const index = e.currentTarget.dataset.index;
  4. let carts = this.data.carts;
  5. let num = carts[index].num;
  6. num = num + 1;
  7. carts[index].num = num;
  8. this.setData({
  9. carts: carts
  10. });
  11. this.getTotalPrice();
  12. },
  13. // 减少数量
  14. minusCount(e) {
  15. const index = e.currentTarget.dataset.index;
  16. let carts = this.data.carts;
  17. let num = carts[index].num;
  18. if(num <= 1){
  19. return false;
  20. }
  21. num = num - 1;
  22. carts[index].num = num;
  23. this.setData({
  24. carts: carts
  25. });
  26. this.getTotalPrice();
  27. }

删除商品

点击删除按钮则从购物车列表中删除当前元素,删除之后如果购物车为空,改变购物车为空标识hasList为false

  1. deleteList(e) {
  2. const index = e.currentTarget.dataset.index;
  3. let carts = this.data.carts;
  4. carts.splice(index,1); // 删除购物车列表里这个商品
  5. this.setData({
  6. carts: carts
  7. });
  8. if(!carts.length){ // 如果购物车为空
  9. this.setData({
  10. hasList: false // 修改标识为false,显示购物车为空页面
  11. });
  12. }else{ // 如果不为空
  13. this.getTotalPrice(); // 重新计算总价格
  14. }
  15. }

总结

虽然一个购物车功能比较简单,但是里面涉及到微信小程序的知识点还是比较多的,适合新手练习掌握。

完整的小程序商城demo含购物车,请戳:wxapp-mall

更多文章:lin-xin/blog

微信赞赏

谢谢支持

分享到:

2人打赏积分

小木茂茂
山瞰麓
山瞰麓 2017-05-11 11:10:48.0

想请教个问题,微信小程序和后台数据交互与APP开发有区别?试过伪静态对接,url+参数对接好用吗。谢谢

S樂
S樂 2017-05-12 20:48:53.0

我是新手,先练练。。

司徒文
司徒文 2017-06-14 13:51:03.0

后台也有的话,就是神作了

小木
小木 2017-06-14 14:20:20.0

赞一个

小丸子
小丸子 2017-06-20 15:55:55.0

赞一个

微风
微风 2018-03-16 19:53:05.0

不错

贝小木
贝小木 2018-03-19 17:34:22.0

学习了

你眉毛轻皱我无法袖手旁观
你眉毛轻皱我无法袖手旁观 2018-03-20 09:05:01.0

我发现我好懒

ghc
ghc 2018-03-21 11:03:52.0

666

超人太郎320
超人太郎320 2018-04-18 17:14:42.0

我就蹭蹭

明夜
明夜 2018-08-01 11:43:48.0

这种光前台的话,不能实际交互吧。

黄海
黄海 2019-08-12 19:26:54.0

不错!

黄千祐
黄千祐 2019-08-30 15:15:26.0

没有效果展示啊

13条评论
我来说两句...
x
 
Ctrl+Enter
作者

淋星雨

淋星雨

APP:0 帖子:1 回复:0 积分:67

已加入社区[3057]天

主人太懒,签名没设置!

作者详情》