微信小程序實現購物車頁面

設計思路:html

1、從網絡上傳入如下Json數據格式的數組 1.購物車id:cid 2.標題title 3.數量num 4.圖片地址 5.價格price 6.小計 7.是否選中selected後端

2、點擊複選框toggle操做 如已經選中的,經點擊變成未選中,反之而反之 點擊依據index做爲標識,而不用cid,方便遍歷api

3、全選操做 首次點擊即爲所有選中,再次點擊爲全不選,全選按鈕自己也跟隨toggle變換數組

4、點擊結算按鈕,將已選中的cid數組取出,以供經過網絡提交到服務端,這裏給個toast做爲結果演示。網絡

5、利用stepper做加減運算,一樣依據index做爲標識,點完寫回num值。xss

6、佈局,全選與結算按鈕底部對齊,購物車商城自適應高度,相似於Android的weight。函數

步驟:佈局

  1. 初始數據渲染

1.1 佈局與樣式表flex

上方是一個商品列表,下方是一個全選按鈕與當即結算按鈕ui

商品列表左部爲商品縮略圖,右上爲商品標題,右下爲商品價格與數量,其中商品數量使用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;
}

圖3-1

1.2 集成WXStepper

1.2.1 複製組件內容

將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
        });
    },

效果如圖:

圖4-1

修正手工改動數量保存到數組

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
        });
    }

效果圖:

圖5-1

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
        });
    }

圖6-1

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;

圖6-1

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()

如圖:

圖6-3

相關文章
相關標籤/搜索