微信小程序 购物车简单实例


Posted in Javascript onOctober 24, 2016

微信小程序,这里实现购物车功能的小demo,有需要此功能的朋友可以参考下。

摘要: 加减商品数量,汇总价格,全选与全不选

设计思路:

一、从网络上传入以下Json数据格式的数组 1.购物车id:cid 2.标题title 3.数量num 4.图片地址 5.价格price 6.小计 7.是否选中selected

二、点击复选框toggle操作 如已经选中的,经点击变成未选中,反之而反之 点击依据index作为标识,而不用cid,方便遍历

三、全选操作 首次点击即为全部选中,再次点击为全不选,全选按钮本身也跟随toggle变换

四、点击结算按钮,将已选中的cid数组取出,以供通过网络提交到服务端,这里给个toast作为结果演示。

五、利用stepper作加减运算,同样依据index作为标识,点完写回num值。

六、布局,全选与结算按钮底部对齐,购物车商城自适应高度,类似于Android的weight。

步骤:

初始数据渲染

1.1 布局与样式表

上方是一个商品列表,下方是一个全选按钮与立即结算按钮

商品列表左部为商品缩略图,右上为商品标题,右下为商品价格与数量,其中商品数量使用WXStepper来实现加减操作

js:初始化一个数据源,这往往是从网络获取的,相关接口可参见:https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html

Page({
  data:{
    carts: [
      {cid:1008,title:'Zippo打火机',image:'https://img12.360buyimg.com/n7/jfs/t2584/348/1423193442/572601/ae464607/573d5eb3N45589898.jpg',num:'1',price:'198.0',sum:'198.0',selected:true},
      {cid:1012,title:'iPhone7 Plus',image:'https://img13.360buyimg.com/n7/jfs/t3235/100/1618018440/139400/44fd706e/57d11c33N5cd57490.jpg',num:'1',price:'7188.0',sum:'7188.0',selected:true},
      {cid:1031,title:'得力订书机',image:'https://img10.360buyimg.com/n7/jfs/t2005/172/380624319/93846/b51b5345/5604bc5eN956aa615.jpg',num:'3',price:'15.0',sum:'45.0',selected:false},
      {cid:1054,title:'康师傅妙芙蛋糕',image:'https://img14.360buyimg.com/n7/jfs/t2614/323/914471624/300618/d60b89b6/572af106Nea021684.jpg',num:'2',price:'15.2',sum:'30.4',selected:false},
      {cid:1063,title:'英雄钢笔',image:'https://img10.360buyimg.com/n7/jfs/t1636/60/1264801432/53355/bb6a3fd1/55c180ddNbe50ad4a.jpg',num:'1',price:'122.0',sum:'122.0',selected:true},
    ]
  }
})

布局文件

<view class="container carts-list">
  <view wx:for="{{carts}}" class="carts-item" data-title="{{item.title}}" data-url="{{item.url}}" bindtap="bindViewTap">
    <view>
     <image class="carts-image" src="{{item.image}}" mode="aspectFill"/>
    </view>
   <view class="carts-text">
    <text class="carts-title">{{item.title}}</text>
    <view class="carts-subtitle">
     <text class="carts-price">{{item.sum}}</text>
     <text>WXStepper</text>
    </view>
   </view>
  </view>
</view>

样式表

/*外部容器*/
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
} 

/*整体列表*/
.carts-list {
  display: flex;
  flex-direction: column;
  padding: 20rpx 40rpx;
}

/*每行单元格*/
.carts-item {
  display: flex;
  flex-direction: row;
  height:150rpx;
  /*width属性解决标题文字太短而缩略图偏移*/
  width:100%;
  border-bottom: 1px solid #eee;
  padding: 30rpx 0;
}

/*左部图片*/
.carts-image {
  width:150rpx;
  height:150rpx;
}


/*右部描述*/
.carts-text {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/*右上部分标题*/
.carts-title {
  margin: 10rpx;
  font-size: 30rpx;
}

/*右下部分价格与数量*/
.carts-subtitle {
  font-size: 25rpx;
  color:darkgray;
  padding: 0 20rpx;
  display: flex;
  flex-direction: row;
  justify-content:space-between;
}

/*价格*/
.carts-price {
  color: #f60;
}

微信小程序 购物车简单实例

1.2 集成WXStepper

1.2.1 复制组件内容

[2016-10-16]

将stepper.wxss的内容复制到cart.wxss中

将stepper.wxml的内容复制到cart.wxml中

与之前的单一组件不同的是:这里要定义数组minusStatuses来与每一个加减按钮相应。当然,合并入carts也是没问题的。

        minusStatuses: ['disabled', 'disabled', 'normal', 'normal', 'disabled']

原来的静态字符WXStepper换成以下的代码

<view class="stepper">
        <!-- 减号 -->
        <text class="{{minusStatuses[index]}}" data-index="{{index}}" bindtap="bindMinus">-</text>
        <!-- 数值 -->
        <input type="number" bindchange="bindManual" value="{{item.num}}" />
        <!-- 加号 -->
        <text class="normal" data-index="{{index}}" bindtap="bindPlus">+</text>
       </view>

js代码bindMinus、bindPlus分别改造为如下:

bindMinus: function(e) {
    var index = parseInt(e.currentTarget.dataset.index);
    var num = this.data.carts[index].num;
    // 如果只有1件了,就不允许再减了
    if (num > 1) {
      num --;
    }
    // 只有大于一件的时候,才能normal状态,否则disable状态
    var minusStatus = num <= 1 ? 'disabled' : 'normal';
    // 购物车数据
    var carts = this.data.carts;
    carts[index].num = num;
    // 按钮可用状态
    var minusStatuses = this.data.minusStatuses;
    minusStatuses[index] = minusStatus;
    // 将数值与状态写回
    this.setData({
      carts: carts,
      minusStatuses: minusStatuses
    });
  },
  bindPlus: function(e) {
    var index = parseInt(e.currentTarget.dataset.index);
    var num = this.data.carts[index].num;
    // 自增
    num ++;
    // 只有大于一件的时候,才能normal状态,否则disable状态
    var minusStatus = num <= 1 ? 'disabled' : 'normal';
    // 购物车数据
    var carts = this.data.carts;
    carts[index].num = num;
    // 按钮可用状态
    var minusStatuses = this.data.minusStatuses;
    minusStatuses[index] = minusStatus;
    // 将数值与状态写回
    this.setData({
      carts: carts,
      minusStatuses: minusStatuses
    });
  },

效果如图:

微信小程序 购物车简单实例

[2016-10-17]

修正手工改动数量保存到数组

1.3 集成LXCheckboxGroup

复制布局文件代码到wxml,这里需要判断一下已选状态,一般购物车勾选状态是记录在网络的。

index值用于传值js,遍历之用。

      

<!-- 复选框图标 -->
    <icon wx:if="{{item.selected}}" type="success_circle" size="20" bindtap="bindCheckbox" data-index="{{index}}"/>
    <icon wx:else type="circle" size="20" bindtap="bindCheckbox" data-index="{{index}}"/>

复选框居中

/*复选框样式*/
.carts-list icon {
  margin-top: 60rpx;
  margin-right: 20rpx;
}

绑定点击复选框事件,对选择状态做反选操作。

bindCheckbox: function(e) {
    /*绑定点击事件,将checkbox样式改变为选中与非选中*/
    //拿到下标值,以在carts作遍历指示用
    var index = parseInt(e.currentTarget.dataset.index);
    //原始的icon状态
    var selected = this.data.carts[index].selected;
    var carts = this.data.carts;
    // 对勾选状态取反
    carts[index].selected = !selected;
    // 写回经点击修改后的数组
    this.setData({
      carts: carts
    });
  }

效果图:

微信小程序 购物车简单实例

1.4 加入全选与立即结算按钮

1.4.1 修改布局文件,实现上述按钮底部对齐,使用flex与固定高度来完成。

减少为3行,看是否还在最底;此外,还要保证悬浮在底部,不被列表项的滚动而滚动。

<view class="carts-footer">
    <view bindtap="bindSelectAll">
      <icon wx:if="{{selectedAllStatus}}" type="success_circle" size="20"/>
      <icon wx:else type="circle" size="20" />
      <text>全选</text>
    </view>
    <view class="button">立即结算</view>
  </view>

之前用<button>立即结算</button>来实现,发现无论如何都不能实现全选部件与结算按钮分散对齐,不响应如下样式

display: flex;
  flex-direction: row;
  justify-content: space-between;

样式表

/*底部按钮*/
.carts-footer {
  width: 100%;
  height: 80rpx;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

/*复选框*/
.carts-footer icon {
  margin-left: 20rpx;
}

/*全选字样*/
.carts-footer text {
  font-size: 30rpx;
  margin-left: 8rpx;
  line-height: 10rpx;
}

/*立即结算按钮*/
.carts-footer .button {
  line-height: 80rpx;
  text-align: center;
  width:220rpx;
  height: 80rpx;
  background-color: #f60;
  color: white;
  font-size: 36rpx;
  border-radius: 0;
  border: 0;
}

1.4.2 全选与全不选事件

实现bindSelectAll事件,改变全选状态

首先定义一个data值,以记录全选状态

selectedAllStatus: false

事件实现:

bindSelectAll: function() {
    // 环境中目前已选状态
    var selectedAllStatus = this.data.selectedAllStatus;
    // 取反操作
    selectedAllStatus = !selectedAllStatus;
    // 购物车数据,关键是处理selected值
    var carts = this.data.carts;
    // 遍历
    for (var i = 0; i < carts.length; i++) {
      carts[i].selected = selectedAllStatus;
    }
    this.setData({
      selectedAllStatus: selectedAllStatus,
      carts: carts
    });
  }

微信小程序 购物车简单实例

1.4.3 立即结算显示目前所选的cid,以供提交到网络,商品数量应该是包括在cid中的,后端设计应该只关注cid与uid

布局文件也埋一下toast,js只要改变toast的显示与否即可。

<toast hidden="{{toastHidden}}" bindchange="bindToastChange">
  {{toastStr}}
</toast>

为立即结算绑定事件bindCheckout,弹出cid弹窗

bindCheckout: function() {
    // 初始化toastStr字符串
    var toastStr = 'cid:';
    // 遍历取出已勾选的cid
    for (var i = 0; i < this.data.carts.length; i++) {
      if (this.data.carts[i].selected) {
        toastStr += this.data.carts[i].cid;
        toastStr += ' ';
      }
    }
    //存回data
    this.setData({
      toastHidden: false,
      toastStr: toastStr
    });
  },
  bindToastChange: function() {
    this.setData({
      toastHidden: true
    });
  }

1.5 底部悬浮固定

1.5.1 商品列表 .carts-list 加入 margin-bottom: 80rpx; 以及修改上边距为零,使得底部部件与分隔不重复出现,padding: 0 40rpx;

1.5.2 底部按钮 .carts-footer 加入 background: white;

1.5.3 .carts-footer 加入

position: fixed;
  bottom: 0;
  border-top: 1px solid #eee;

微信小程序 购物车简单实例

1.6 汇总

1.6.1 首先定义一个数据源,并在布局文件中埋坑

total: ''

<text>{{total}}</text>

1.6.2 通用汇总函数

sum: function() {
    var carts = this.data.carts;
    // 计算总金额
    var total = 0;
    for (var i = 0; i < carts.length; i++) {
      if (carts[i].selected) {
        total += carts[i].num * carts[i].price;
      }
    }
    // 写回经点击修改后的数组
    this.setData({
      carts: carts,
      total: '¥' + total
    });
  }

然后分别在bindMinus bindPlus bindCheckbox bindSelectAll onLoad中调用this.sum()

如图:

微信小程序 购物车简单实例

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
javascript 关于# 和 void的区别分析
Oct 26 Javascript
JQuery的Validation插件中Remote验证的中文问题
Jul 26 Javascript
js Math 对象的方法
Sep 01 Javascript
jQuery类选择器用法实例
Dec 23 Javascript
DOM节点深度克隆函数cloneNode()用法实例
Jan 12 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
Dec 03 Javascript
举例讲解如何判断JavaScript中对象的类型
Apr 22 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
Nov 01 Javascript
JavaScript之DOM_动力节点Java学院整理
Jul 03 Javascript
vue 实现复制内容到粘贴板clipboard的方法
Mar 17 Javascript
JS实现的字符串数组去重功能小结
Jun 17 Javascript
vue选项卡切换登录方式小案例
Sep 27 Javascript
Select2.js下拉框使用小结
Oct 24 #Javascript
微信小程序 绘图之饼图实现
Oct 24 #Javascript
用jmSlip编写移动端顶部日历选择控件
Oct 24 #Javascript
微信小程序 富文本转文本实例详解
Oct 24 #Javascript
微信小程序 参数传递详解
Oct 24 #Javascript
10分钟掌握XML、JSON及其解析
Dec 06 #Javascript
JavaScript的new date等日期函数在safari中遇到的坑
Oct 24 #Javascript
You might like
Zend的Registry机制的使用说明
2013/05/02 PHP
php上传大文件设置方法
2016/04/14 PHP
win10下 php安装seaslog扩展的详细步骤
2020/12/04 PHP
JavaScript 三种不同位置代码的写法
2009/10/25 Javascript
jquery URL参数判断,确定菜单样式
2010/05/31 Javascript
初窥JQuery-Jquery简介 入门了解篇
2010/11/25 Javascript
jQuery 源码分析笔记(5) jQuery.support
2011/06/19 Javascript
jQuery页面滚动浮动层智能定位实例代码
2011/08/23 Javascript
屏蔽相应键盘按钮操作
2014/03/10 Javascript
node.js中Socket.IO的进阶使用技巧
2014/11/04 Javascript
javascript属性访问表达式用法分析
2015/04/25 Javascript
微信小程序  checkbox组件详解及简单实例
2017/01/10 Javascript
jqGrid翻页时数据选中丢失问题的解决办法
2017/02/13 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
Node.js readline模块与util模块的使用
2018/03/01 Javascript
详解django模板与vue.js冲突问题
2019/07/07 Javascript
JavaScript switch语句使用方法简介
2019/12/30 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
[09:23]国际邀请赛采访专栏:iG战队VK,Tongfu战队Cu
2013/08/05 DOTA
[02:10]探秘浦东源深体育馆 DOTA2 Supermajor不见不散
2018/05/17 DOTA
[42:52]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python MySQLdb 使用utf-8 编码插入中文数据问题
2018/03/13 Python
详解Python中的type和object
2018/08/15 Python
python的pytest框架之命令行参数详解(下)
2019/06/27 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
python开发一个解析protobuf文件的简单编译器
2020/11/17 Python
Html5页面二次分享的实现
2018/07/30 HTML / CSS
大学生毕业自我鉴定范文
2013/09/19 职场文书
2014年教师节寄语
2014/04/03 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
2015年综治维稳工作总结
2015/04/07 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
甲午大海战观后感
2015/06/02 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书
Python绘画好看的星空图
2022/03/17 Python