本来想做搬运工的, 网上找了一些案列, 找了三个小时都没有找到自己想要的, 或者有很多BUG, 一气之下就自己写了. 有不对的地方望提出更正~~
正文:
1 初始数据
/**
* 页面的初始数据
*/
data: {
adminShow: true,//编辑或完成
totalPrice: 0,//总金额
allselect:false,//是否全选
selectArr: [], //已选择的商品
cartData:[
{
"id":1,
"amount":2,
"price":50,
"name":"手机",
"checked":false,
"image":"https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640"
},
{
"id":2,
"amount":1,
"price":10,
"name":"显示器",
"checked": false,
"image":"https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640"
},
{
"id":3,
"amount":5,
"price":120,
"name":"可乐",
"checked": false,
"image":"https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640"
},
{
"id":4,
"amount":10,
"price":50,
"name":"手机",
"checked": false,
"image":"https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640"
},
{
"id":4,
"amount":1,
"price":10,
"name":"芝麻",
"checked": false,
"image":"https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640"
},
],
},
2 wxml(类名不会取 , 请勿吐槽, 大部分都是从网上找的案例复制过来的类名 , 都没改动) :
<view class="cart_body">
<view class="cart_item">
<label wx:for="{{cartData}}" wx:key="this" data-index="{{index}}" catchtap="checkTap">
<!-- 选中的按钮, 就两张图片 -->
<view class="check_box">
<image class="check_img" hidden="{{item.checked}}" src="/images/icon_yn@2x.png"></image>
<image class="check_img" hidden="{{!item.checked}}" src="/images/iocn_ys@2x.png"></image>
</view>
<view class="cart_image">
<image class="cart_img" src="{{item.image}}" mode='aspectFill'></image>
</view>
<view class="cart_content">
<view class="content_title fs_12 fc_333">{{item.name}}</view>
<view class="content_price">
<view class="fc_price fs_18 fw_bold">¥{{item.price}}</view>
<view class="goods_number_container">
<view class="goods_number_icon_container">
<image
class="goods_number_icon"
src="/images/btn_reduce@2x.png"
data-types="minus"
data-index="{{index}}"
catchtap="numchangeTap"></image>
</view>
<view class="goods_number">{{item.amount}}</view>
<view class="goods_number_icon_container">
<image
class="goods_number_icon"
src="/images/btn_plus@2x.png"
data-types="add"
data-index="{{index}}"
catchtap="numchangeTap"></image>
</view>
</view>
</view>
</view>
</label>
</view>
</view>
<!-- 全选 计算价格 编辑 结算 -->
<view class="cart_total_container">
<image class="checkAllBox" src="/images/icon_yn@2x.png" hidden="{{allselect}}" catchtap="allcheckTap"></image>
<image class="checkAllBox" src="/images/iocn_ys@2x.png" hidden="{{!allselect}}" catchtap="allcheckTap"></image>
<view class="fs_12 fc_333" catchtap="allcheckTap">全选</view>
<view class="fc_333 fs_12 totalPrice">合计:¥ {{totalPrice}}</view>
<view class="clearingBox" wx:if="{{adminShow}}">
<view class="btn editbtn fs_12 fc_666" catchtap='adminTap'>编辑</view>
<view class="btn clearbtn fs_12" bindtap="toApply">去结算({{selectArr.length}})</view>
</view>
<view class="clearingBox" wx:else>
<view class="btn editbtn fs_12 fc_666" catchtap="deleteshopTap">删除</view>
<view class="btn clearbtn fs_12" catchtap='adminTap'>完成</view>
</view>
</view>
3, 我的业务逻辑:
1, 选中单个商品, 放到已选择的商品数组, 计算价格, 判断是否全选
2, 取消单个商品, 从已选择的商品数组中移除, 计算价格
3, 点击全选, 所有数据都放到已选择商品数组里, 计算价格
4,取消全选, 已选择商品数据清空, 价格清空
5,删除商品, 清空已选择商品的数组, 删除对应的初始数据, 价格清空
6, 数量加减, 未选择的商品数量加减不计算价格, 只改变初始数据, 选中的商品数量加减计算价格,改变初始数据
总结有这么几个功能: 单个商品选择、全选、判断是否全选、删除、数量加减、计算价格、编辑或完成显示的按钮、结算
//计算价格
calculateTotal:function(){
var selectArr = this.data.selectArr; //已选择的商品
var totalPrice = 0;
if(selectArr.length){ //如果存在商品就计算价格
for(var i=0;i<selectArr.length;i++){
totalPrice += selectArr[i].amount * selectArr[i].price;
}
totalPrice = totalPrice.toFixed(2); //乘法有点问题, 需要保留一下小数
console.log("计算价格:",totalPrice)
this.setData({
totalPrice:totalPrice
})
} else{ //不存在商品就把总价格置为 0
this.setData({
totalPrice:0
})
}
},
//判断是否为全选
judgmentAll: function () {
var cartData = this.data.cartData; //初始数据
var selectArr = this.data.selectArr; //已选择的商品
if(selectArr.length == cartData.length){ //长度相等就是全部选上了
this.setData({
allselect: true
})
} else {
this.setData({
allselect: false
})
}
},
//全选
allcheckTap:function(){
var that = this;
var cartData = that.data.cartData; //初始数据
var selectArr = []; //定义空数组
var allselect = !that.data.allselect; //data里的是否全选先改变状态存着
if(allselect){ //如果为真, 初始数据里的每条checked变为true, 然后push到定义的空数组里
for (var i = 0; i < cartData.length; i++) {
cartData[i].checked = true;
selectArr.push(cartData[i])
}
}else{ //不为真就变成false, 定义的数组再置空一次
for (var i = 0; i < cartData.length; i++) {
cartData[i].checked = false;
}
selectArr = [];
}
that.setData({ //重新设置数据
cartData: cartData, //初始的数据
allselect: allselect, //全选的状态
selectArr: selectArr //已选择的商品
})
that.calculateTotal(); // 最后计算一次价格 (计算价格放到重置数据之前会出问题)
},
//单个商品选择
checkTap:function(e){
var index = e.currentTarget.dataset.index; //取到渲染的下标
var cartData = this.data.cartData; //初始数据
var selectArr = this.data.selectArr; //已选择的商品数组
cartData[index].checked = !cartData[index].checked //没选中的就要选中, 选中了的就取消选中状态
if (cartData[index].checked){ //如果选中了, 就放到一选择的商品数组里
for (var i = 0; i < cartData.length; i++) {
if (cartData[i] == cartData[index]) {
selectArr.push(cartData[index])
}
}
this.judgmentAll(); //计算价格
} else{ //取消选中就从已选择的商品数组里移除
for (var i = 0; i < selectArr.length; i++) {
if(selectArr[i].id == cartData[index].id){
selectArr.splice(i,1)
}
}
this.judgmentAll(); //选择的时候要判断是不是已经选择了全部的
}
this.calculateTotal(); //计算一次价格
console.log("已选择的商品:",selectArr)
this.setData({ //重置数据
cartData:cartData,
selectArr: selectArr
})
},
//数量加减
numchangeTap:function(e){
var types = e.currentTarget.dataset.types; //加和减的两张图片上分别设置了types属性
var index = e.currentTarget.dataset.index; //获取下标
var cartData = this.data.cartData; //初始数据
if (types == 'minus') { //减
var amount = cartData[index].amount;
if(amount <= 1){ //不允许商品数量小于1 , 都添加到购物车了还要减到0是几个意思? 反正有个删除按钮
return;
} else {
cartData[index].amount--;
this.setData({
cartData: cartData
})
this.calculateTotal(); //计算价格
}
}
if (types == "add") { //加
cartData[index].amount++; //加就不判断了, 加到二十二世纪去都行
this.setData({
cartData: cartData
})
this.calculateTotal(); //计算价格
}
},
//删除商品
deleteshopTap:function(){ //要删除 肯定是已经选中了的商品, 所以肯定在 selectArr里面
//这里好像有一点小BUG, 不过, 我忘记了.
var cartData = this.data.cartData; //初始数据
var selectArr = this.data.selectArr; //已选择的商品数组
if(selectArr.length){ //如果以选择的商品数组里有长度
for (var i = 0; i < cartData.length; i++) {
for (var j = 0; j < selectArr.length; j++) {
if (cartData[i].id == selectArr[j].id) { //把初始数据的对应id的数据删掉就好了
cartData.splice(i, 1);
}
}
}
this.setData({ //重置一下数据
cartData: cartData,
selectArr: [] //已选择的数组置空
})
this.calculateTotal(); //计算价格
}
},
//编辑或完成
adminTap:function(){ //切换四个按钮的显示
this.setData({
adminShow: !this.data.adminShow
})
},
//结算
toApply:function(){
console.log("已选择的商品:",this.data.selectArr)
},
从接口获取到的数据自己改成那种格式就可以了.
// wxss
.cart_body{
box-sizing: border-box;
padding: 0 32rpx;
}
.cart_item{
box-sizing: border-box;
padding-bottom: 100rpx;
}
.check_img{
width: 40rpx;
height: 40rpx;
margin-top: 76rpx;
}
label{
display: flex;
padding: 46rpx 0;
}
.cart_image{
width: 192rpx;
height: 192rpx;
margin-left: 32rpx;
}
.cart_img{
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.cart_content{
margin-left: 20rpx;
flex:1;
display: flex;
flex-flow: column wrap;
justify-content: space-between;
}
.content_title{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp:2;
line-clamp: 2;
-webkit-box-orient: vertical;
}
.content_price{
display: flex;
justify-content: space-between;
}
.goods_number_container{
width: 170rpx;
display: flex;
justify-content: space-between;
}
.goods_number_icon_container{
width: 44rpx;
height:44rpx;
}
.goods_number_icon{
width:100%;
height:100%;
}
.goods_number{
flex:1;
text-align: center;
}
.cart_total_container{
height: 100rpx;
line-height: 88rpx;
background: #f5f5f5;
position: fixed;
bottom:0;
left:0;
right:0;
box-sizing: border-box;
padding: 12rpx 32rpx;
display: flex;
}
.checkAllBox{
border-radius: 50%;
height: 40rpx;
width: 40rpx;
margin-top: 23rpx;
margin-right: 8rpx;
}
.totalPrice{
flex:1;
margin-left: 40rpx;
}
.clearingBox{
width: 300rpx;
display: flex;
justify-content: space-between;
}
.btn{
width: 140rpx;
text-align: center;
border-radius: 36rpx;
line-height: 72rpx;
}
.editbtn{
border: 1px solid #666666;
background: #fff;
}
.clearbtn{
background: #ff5c4d;
color: #fff;
}
网友评论