美文网首页
vuejs仿美团,饿了么项目之——购物车篇

vuejs仿美团,饿了么项目之——购物车篇

作者: 从小就很瘦 | 来源:发表于2018-07-27 14:28 被阅读0次

    上一篇写了个商品加减的组件,这篇说一下购物车。只有当添加商品的时候,也就是存在count这个key的时候,购物车的样式才改变,计算属性总价格,总数量才实现。所以我们先在good.vue中判断下此时是否点击了添加商品事件,也就是判断是否有count;
    我写的本地的json数据是类似这样的:

    {
        "data": {
            "food":[
                {
                    "name":"饮料",
                    "detail": [
                        {
                            "name": "芬达",
                            "price": 3
                        },
                        {
                            "name": "可乐",
                            "price": 4
                        },
                        {
                            "name": "雪碧",
                            "price": 5
                        }
                    ]
                },
                {
                    "name":"水果",
                    "detail": [
                        {
                            "name": "香蕉",
                            "price": 3
                        },
                        {
                            "name": "西瓜",
                            "price": 4
                        },
    

    在计算属性中:

    checkCount(){
                    let foodlist = [];
                    this.food.forEach(val => {
                        val.detail.forEach(val => {
                            if(val.count){
                                foodlist.push(val) 
                            }
                        })
                    })
                    return foodlist;
                    
                },
    

    data中的food数组已经获取了数据中的food,所以在checkCount()中如果有count,那么就用foodlist数组存储food.detail,也就是商品的有关数据。然后在组件中通过props传给子组件shopcart。
    下面就简单了,子组件获取数据之后,判断如果有count,说明添加商品的事件被触发,那么就在computed写2个方法,计算总价格和总数量。同时用v-show来控制css样式。
    详细代码如下:

    <template>
        <div class="shopcart">
            <div class="left">
                <div class="circle" :class="{'highlight': totalCount}">
                    <div class="num-red" v-show="totalCount">
                        {{totalCount}}
                    </div>
                </div>
                <div class="left-text-before" v-show="!totalCount">
                    {{check.trackingBefore}}
                </div>
                <div class="left-text-after" v-show="totalCount">
                    <div class="total-money">
                        ¥{{totalMoney}}
                    </div>
                    <div class="tracking">
                        {{check.trackingBefore}}    
                    </div>
    
                </div>
            </div>
            <div class="right" :class="{'highlight': totalCount}">
                {{checkAll}}
            </div>
        </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    check: {
                        trackingBefore:'另需配送费¥5',
                        checkBefore: '¥20起送',
                        checkAfter: '去结算',
                    },
    
                }
            },
            props: {
                foodlist:{
                    type: Array
                }
            },
            methods: {
    
            },
            computed: {
                totalMoney(){
                    let total = 0;
                    this.foodlist.forEach(val => {
                        if(!val.count){
                            return
                        }else{
                            total += val.count*val.price
                        }
                    })
                    return total
                },
                totalCount(){
                    let num = 0;
                    this.foodlist.forEach(val => {
                        if(!val.count){
                            return
                        }else{
                            num += val.count
                        }
                    })
                    return num
                },
                checkAll(){
                    if(this.totalCount){
                        return this.check.checkAfter
                    }else{
                        return this.check.checkBefore
                    }
                }
            }
        }
    </script>
    <style>
    .shopcart {
        width: 100%;
        background: #514f4f;
        position: fixed;
        bottom: 0;
        height: 50px;
        display: flex;
    }
    .left{
        flex:1;
    }
    .circle {
        width: 50px;
        height: 50px;
        background: #726d6d;
        border-radius: 50%;
        position: relative;
        left: 10px;
        bottom: 16px;
        float: left;
    }
    .circle .num-red {
        position: absolute;
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background: red;
        color: white;
        font-size: 9px;
        line-height: 15px;
        text-align: center;
        right: 0;
        top: 0;
    }
    .left-text-before{
        position: relative;
        left: 18px;
        font-size: 14px;
        line-height: 50px;
        color: #c4c4c4;
        float: left;
    }
    .left-text-after {
        position: relative;
        left: 18px;
        color: #c4c4c4;
        float: left;
    }
    .left-text-after .total-money {
        font-size: 24px;
        line-height: 28px;
    }
    .left-text-after .tracking {
        font-size: 11px;
        margin-top: 3px;
    }
    .right {
        flex: 0 0 110px;
        line-height: 50px;
        text-align: center;
        color:#c4c4c4;
    }
    .highlight {
        background: #FFD161;
        color: #2D2B2A;
    }
    </style>
    

    那么菜单上如何同步红色数量的显示呢?
    在good.vue中,红色数量DOM结构如下

                    <li ref="menuItem" class="menu-item" :class="{'current': currentIndex == index}" @click="selectIndex(index)" v-for="(item, index) in food">
                        {{item.name}}
                        <div class="num-red" v-show="redNum(item.detail)">
                            {{redNum(item.detail)}}
                        </div>
                    </li>
    

    在methods中,detail参数来接受传入的item,detail,也就是JSON数据中的detail数组。首先要判断数组是否存在,否则可能报错,如果存在,那么遍历对象,获取各个商品的count赋值给num,return num

        redNum(detail){
    
                    if(detail){
                        let num = 0
                        detail.forEach(val => {
                            if(val.count){
                                num += val.count
                            }
                        })
                        return num
                    }
                }
    

    这样就实现了,点击添加商品,底部购物车显示商品总价和数量,样式改变,左侧菜单也会有商品数量的显示。效果如下:


    Animation.gif

    只因为count的改变,从而改变了好多东西,充分体现了vue数据操控模型的魅力所在。
    好,下篇写一下关于购物车列表的功能。

    相关文章

      网友评论

          本文标题:vuejs仿美团,饿了么项目之——购物车篇

          本文链接:https://www.haomeiwen.com/subject/yxzwmftx.html