
shopcart.gif
本來想做搬運工的, 網上找了一些案列, 找了三個小時都沒有找到自己想要的, 或者有很多BUG, 一氣之下就自己寫了. 有不對的地方望提出更正~~
正文:
1 初始數(shù)據(jù)
/**
* 頁面的初始數(shù)據(jù)
*/
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, 我的業(yè)務邏輯:
1, 選中單個商品, 放到已選擇的商品數(shù)組, 計算價格, 判斷是否全選
2, 取消單個商品, 從已選擇的商品數(shù)組中移除, 計算價格
3, 點擊全選, 所有數(shù)據(jù)都放到已選擇商品數(shù)組里, 計算價格
4,取消全選, 已選擇商品數(shù)據(jù)清空, 價格清空
5,刪除商品, 清空已選擇商品的數(shù)組, 刪除對應的初始數(shù)據(jù), 價格清空
6, 數(shù)量加減, 未選擇的商品數(shù)量加減不計算價格, 只改變初始數(shù)據(jù), 選中的商品數(shù)量加減計算價格,改變初始數(shù)據(jù)
總結有這么幾個功能: 單個商品選擇、全選、判斷是否全選、刪除、數(shù)量加減、計算價格、編輯或完成顯示的按鈕、結算
//計算價格
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); //乘法有點問題, 需要保留一下小數(shù)
console.log("計算價格:",totalPrice)
this.setData({
totalPrice:totalPrice
})
} else{ //不存在商品就把總價格置為 0
this.setData({
totalPrice:0
})
}
},
//判斷是否為全選
judgmentAll: function () {
var cartData = this.data.cartData; //初始數(shù)據(jù)
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; //初始數(shù)據(jù)
var selectArr = []; //定義空數(shù)組
var allselect = !that.data.allselect; //data里的是否全選先改變狀態(tài)存著
if(allselect){ //如果為真, 初始數(shù)據(jù)里的每條checked變?yōu)閠rue, 然后push到定義的空數(shù)組里
for (var i = 0; i < cartData.length; i++) {
cartData[i].checked = true;
selectArr.push(cartData[i])
}
}else{ //不為真就變成false, 定義的數(shù)組再置空一次
for (var i = 0; i < cartData.length; i++) {
cartData[i].checked = false;
}
selectArr = [];
}
that.setData({ //重新設置數(shù)據(jù)
cartData: cartData, //初始的數(shù)據(jù)
allselect: allselect, //全選的狀態(tài)
selectArr: selectArr //已選擇的商品
})
that.calculateTotal(); // 最后計算一次價格 (計算價格放到重置數(shù)據(jù)之前會出問題)
},
//單個商品選擇
checkTap:function(e){
var index = e.currentTarget.dataset.index; //取到渲染的下標
var cartData = this.data.cartData; //初始數(shù)據(jù)
var selectArr = this.data.selectArr; //已選擇的商品數(shù)組
cartData[index].checked = !cartData[index].checked //沒選中的就要選中, 選中了的就取消選中狀態(tài)
if (cartData[index].checked){ //如果選中了, 就放到一選擇的商品數(shù)組里
for (var i = 0; i < cartData.length; i++) {
if (cartData[i] == cartData[index]) {
selectArr.push(cartData[index])
}
}
this.judgmentAll(); //計算價格
} else{ //取消選中就從已選擇的商品數(shù)組里移除
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({ //重置數(shù)據(jù)
cartData:cartData,
selectArr: selectArr
})
},
//數(shù)量加減
numchangeTap:function(e){
var types = e.currentTarget.dataset.types; //加和減的兩張圖片上分別設置了types屬性
var index = e.currentTarget.dataset.index; //獲取下標
var cartData = this.data.cartData; //初始數(shù)據(jù)
if (types == 'minus') { //減
var amount = cartData[index].amount;
if(amount <= 1){ //不允許商品數(shù)量小于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; //初始數(shù)據(jù)
var selectArr = this.data.selectArr; //已選擇的商品數(shù)組
if(selectArr.length){ //如果以選擇的商品數(shù)組里有長度
for (var i = 0; i < cartData.length; i++) {
for (var j = 0; j < selectArr.length; j++) {
if (cartData[i].id == selectArr[j].id) { //把初始數(shù)據(jù)的對應id的數(shù)據(jù)刪掉就好了
cartData.splice(i, 1);
}
}
}
this.setData({ //重置一下數(shù)據(jù)
cartData: cartData,
selectArr: [] //已選擇的數(shù)組置空
})
this.calculateTotal(); //計算價格
}
},
//編輯或完成
adminTap:function(){ //切換四個按鈕的顯示
this.setData({
adminShow: !this.data.adminShow
})
},
//結算
toApply:function(){
console.log("已選擇的商品:",this.data.selectArr)
},
從接口獲取到的數(shù)據(jù)自己改成那種格式就可以了.
// 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;
}