Vue實戰—購物車詳情頁面的實現(11)

上次我們爲商品分類菜單添加了顯示購物數量,這篇我們繼續推進項目,來實現購物車的詳情頁面,在開始之前我們先看它在頁面中的樣子:
圖片描述

如上所示,此頁面包含了購物列表,而它由商品名稱,單價,增減商品功能構成,增減商品功能我們在商品列表中實現過,那麼我們現在可以進行復用。

搭出購物車結構

我們將購物車底部構建出來,

<templete>
<div class="shopcart" :class="{'highligh':totalCount>0}">
        <div class="shopcart-wrapper">
            
        </div>
</div>
</templete>

老情況,在templete模板下的shopcart-wrapper內完成底部購物車一欄:

1 count大於0.讓它打開

 <!-- 左=>內容包含購物車icon 金額 配送費 -->
            <div class="content-left">
                <div class="logo-wrapper" :class="{'highligh':totalCount>0}" @click="toggleList">
                    <span class="icon-shopping_cart logo" :class="{'highligh':totalCount>0}"></span>
                    <i class="num" v-show="totalCount">{{totalCount}}</i>
                </div>
                <div class="desc-wrapper">
                    <p class="total-price" v-show="totalPrice">¥{{totalPrice}}</p>
                    <p class="tip" :class="{'highligh':totalCount>0}">另需{{poiInfo.shipping_fee_tip}}</p>
                </div>
            </div>
            <!-- 去結算 -->
            <div class="content-right" :class="{'highligh':totalCount>0}">
                {{payStr}}
            </div>

搭建所選商品列表

圖片描述

如圖所示,我們分好結構,緊接着搭建所選商品的列表

所選商品的列表 shopcart-list默認隱藏的,也就是說我們在沒有選擇食品的時候,點擊購物車它不會展開。

1.list-hearder,左右結構包括1號口袋與清空購物車

2.list-content 列表,存放我們選擇的食物

2.1左邊是我們的食物名字,商品描述;右側是數量,加減商品的組件。

<div class="shopcart-list" v-show="listShow" :class="{'show':listShow}">
                <!--列表頂部滿減信息-->
                <div class="list-top" v-if="poiInfo.discounts2">
                    {{poiInfo.discounts2[0].info}}
                </div>
                <!--1號口袋 清空功能-->
                <div class="list-header">
                    <h3 class="title">1號口袋</h3>
                    <div class="empty" @click="emptyFn">
                        <img src="./ash_bin.png" />
                        <span>清空購物車</span>
                    </div>
                </div>
                <!--所選商品列表-->
                <div class="list-content" ref='listContent'>
                    <ul>
                        <li class="food-item" v-for="food in selectFoods">
                            <div class="desc-wrapper">
                                <!--左側-->
                                <div class="desc-left">
                                    <!--所選商品名字-->
                                    <p class="name">{{food.name}}</p>
                                    <!--所選商品描述 unit 例 des 霆鋒苦辣雞腿堡1個-->
                                    <p class="unit" v-show="!food.description">{{food.unit}}</p>
                                    <p class="description" v-show="food.description">{{food.description}}</p>
                                </div>
                                <!--商品單價-->
                                <div class="desc-right">
                                    <span class="price">¥{{food.min_price}}</span>
                                </div>
                            </div>
                            <!--複用商品增減組件 Cartcontrol-->
                            <div class="cartcontrol-wrapper">
                                <Cartcontrol :food='food'></Cartcontrol>
                            </div>
                        </li>
                    </ul>
                </div>
                <div class="list-bottom"></div>
            </div>

加入遮罩層

        <!-- 遮罩層 -->
        <div class="shopcart-mask" v-show="listShow" @click="hideMask()"></div>


到這裏,結構咱們就搭好了。

註冊組件,添加功能

我們通過props爲購物車組件傳入所需要的數據;

計算屬性:

通過totalCount計算所選的商品數量;

通過totalPrice計算所選商品的總價;

通過payStr控制去結算;

listShow是我們控制購物車詳情頁展示的要點,依據totalCount所選商品數量對fold摺疊進行控制,fold爲true,商品數量爲0.購物車詳情頁爲摺疊狀態。

接着我們將狀態取反賦值到show,並且依據show,來控制商品詳情頁面商品一定多時,可以進行鼠標滾動。

方法:

通過toggleList點擊購物車logo時候,進行判斷,如果沒有選擇商品那麼我們什麼也不做。如果我們選擇了商品,那麼將fold取反。因爲我們在計算屬性listShow中設置過實例中的fold屬性爲true,所有它是摺疊的。在我們取反後,它就會展開。

emptyFn清空購物車

最後我們點擊遮罩層的時候,讓遮罩層隱藏,也就是fold爲true。

<script>
    // 導入BScroll
    import BScroll from 'better-scroll'
    // 導入Cartcontrol
    import Cartcontrol from 'components/Cartcontrol/Cartcontrol'

    export default {
        data() {
            return {
                fold: true
            }
        },
        props: {
            poiInfo: {
                type: Object,
                default: {}
            },
            selectFoods: {
                type: Array,
                default() {
                    return [
                        //                        {
                        //                            min_price: 10,
                        //                            count: 3
                        //                        },
                        //                        {
                        //                            min_price: 7,
                        //                            count: 1
                        //                        }
                    ];
                }
            }
        },
        computed: {
            // 總個數
            totalCount() {
                let num = 0;
                this.selectFoods.forEach((food) => {
                    num += food.count;
                });

                return num;
            },
            // 總金額
            totalPrice() {
                let total = 0;
                this.selectFoods.forEach((food) => {
                    total += food.min_price * food.count;
                });

                return total;
            },
            payStr() {
                if(this.totalCount > 0) {
                    return "去結算";
                } else {
                    return this.poiInfo.min_price_tip;
                }
            },
            listShow() {
                if(!this.totalCount) { // 個數爲0
                    this.fold = true;

                    return false;
                }

                let show = !this.fold;

                // BScoll相關
                if(show) {
                    this.$nextTick(() => {
                        if(!this.shopScroll) {
                            this.shopScroll = new BScroll(this.$refs.listContent, {
                                click: true
                            });
                        } else {
                            this.shopScroll.refresh();
                        }
                    });
                }

                return show;
            }
        },
        methods: {
            toggleList() {
                if(!this.totalCount) { // 個數爲0
                    return;
                }
                this.fold = !this.fold;
            },
            emptyFn() {
                this.selectFoods.forEach((food) => {
                    food.count = 0;
                });
            },
            hideMask() {
                this.fold = true;
            }
        },
        components: {
            Cartcontrol,
            BScroll
        }
    }
</script>

樣式

<style>
.shopcart-wrapper{
    width: 100%;
    height: 51px;
    background: #514f4f;
    position: fixed;
    left: 0;
    bottom: 0;
    display: flex;
    z-index: 99;
}
.shopcart-wrapper.highligh{
    background: #2d2b2a;
}


.shopcart-wrapper .content-left{
    flex: 1;
}
.shopcart-wrapper .content-left .logo-wrapper{
    width: 50px;
    height: 50px;
    background: #666666;
    border-radius: 50%;
    position: relative;
    top: -14px;
    left: 10px;
    text-align: center;
    float: left;
}
.shopcart-wrapper .content-left .logo-wrapper.highligh{
    background: #ffd161;
}
.shopcart-wrapper .content-left .logo-wrapper .logo{
    font-size: 28px;
    color: #c4c4c4;
    line-height: 50px;
}
.shopcart-wrapper .content-left .logo-wrapper .logo.highligh{
    color: #2D2B2A;
}
.shopcart-wrapper .content-left .logo-wrapper .num{
    width: 15px;
    height: 15px;
    line-height: 15px;
    border-radius: 50%;
    font-size: 9px;
    color: white;
    background: red;
    position: absolute;
    right: 0;
    top: 0;
}
.shopcart-wrapper .content-left .desc-wrapper{
    float: left;
    margin-left: 13px;
}
.shopcart-wrapper .content-left .desc-wrapper .total-price{
    font-size: 18px;
    line-height: 33px;
    color: white;
}
.shopcart-wrapper .content-left .desc-wrapper .tip{
    font-size: 12px;
    color: #bab9b9;
    line-height: 51px;
}
.shopcart-wrapper .content-left .desc-wrapper .tip.highligh{
    line-height: 12px;
}


.shopcart-wrapper .content-right{
    flex: 0 0 110px;
    font-size: 15px;
    color: #BAB9B9;
    line-height: 51px;
    text-align: center;
    font-weight: bold;
}
.shopcart-wrapper .content-right.highligh{
    background: #FFD161;
    color: #2D2B2A;
}




.shopcart-wrapper .shopcart-list{
    position: absolute;
    left: 0;
    top: 0;
    z-index: -1;
    width: 100%;
}
.shopcart-wrapper .shopcart-list.show{
    transform: translateY(-100%);
}

.shopcart-wrapper .shopcart-list .list-top{
    height: 30px;
    text-align: center;
    font-size: 11px;
    background: #f3e6c6;
    line-height: 30px;
    color: #646158;
}

.shopcart-wrapper .shopcart-list .list-header{
    height: 30px;
    background: #F4F4F4;
}
.shopcart-wrapper .shopcart-list .list-header .title{
    float: left;
    border-left: 4px solid #53c123;
    padding-left: 6px;
    line-height: 30px;
    font-size: 12px;
}
.shopcart-wrapper .shopcart-list .list-header .empty{
    float: right;
    line-height: 30px;
    margin-right: 10px;
    font-size: 0;
}
.shopcart-wrapper .shopcart-list .list-header .empty img{
    height: 14px;
    margin-right: 9px;
    vertical-align: middle;
}
.shopcart-wrapper .shopcart-list .list-header .empty span{
    font-size: 12px;
    vertical-align: middle;
}

.shopcart-wrapper .shopcart-list .list-content{
    max-height: 360px;
    overflow: hidden;
    background: white;
}
.shopcart-wrapper .shopcart-list .list-content .food-item{
    height: 38px;
    padding: 12px 12px 10px 12px;
    border-bottom: 1px solid #F4F4F4;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper{
    float: left;
    width: 240px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left{
    float: left;
    width: 170px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .name{
    font-size: 16px;
    margin-bottom: 8px;
    
    /* 超出部分隱藏*/
    -webkit-line-clamp: 1;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
    height: 16px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .unit{
    font-size: 12px;
    color: #B4B4B4;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .description{
    font-size: 12px;
    color: #B4B4B4;
        
    /* 超出部分隱藏*/
    overflow: hidden;
    height: 12px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-right{
    float: right;
    width: 70px;
    text-align: right;    
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-right .price{
    font-size: 12px;
    line-height: 38px;
}

.shopcart-wrapper .shopcart-list .list-content .food-item .cartcontrol-wrapper{
    float: right;
    margin-top: 6px;
}


.shopcart .shopcart-mask{
    position: fixed;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    z-index: 98;
    background: rgba(7,17,27,0.6);
}
    
</style>


總結

我們從搭購物車結構,到所選商品列表細化,這裏我們複用了增減商品的組件,然後加入遮罩層。通過計算屬性與方法,加入控制邏輯完成了購物車的詳情頁面。
下一篇我們來實現商品的詳情頁面,下週我們不見不散。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章