只有第一次点击加号才会更新最下边的购物车

来源:17-17 cartcontrol组件(3)

MorningDuGe

2017-05-17

只有第一次点击加号才会更新最下边的购物车数据,再次点击同一个加号就没反应了,减号从来都没有反应,只有点击其他加号后才会更新最下边的购物车数据,更新的数据是正确的

以下是cartcontrol.vue

<template>
    <div class="cart-control">
        <transition name="move">
            <div class="decrease-count control" @click="removeCart($event)" v-show="food.count>0">
                <i class="icon-remove_circle_outline"></i>
            </div>
        </transition>
        <div class="count control" v-show="count>0">{{count}}</div>
        <div class="increase-count control" @click="addCart($event)">
            <i class="icon-add_circle"></i>
        </div>
    </div>
</template>

<script type="text/ecmascript-6">
    import Vue from 'Vue';
    export default {
        data () {
            return {
                count: 0
 };
        },
        props: {
            food: {
                type: Object
            }
        },
        methods: {
            addCart (event) {
                if (!event._constructed) {
                    return;
                }
                if (!this.food.count) {
                    Vue.set(this.food, 'count', 1);
                    this.count = 1;
                } else {
                    this.count++;
                    this.food.count = this.count;
                }
            },
            removeCart (event) {
                if (!event._constructed) {
                    return;
                }
                this.count--;
                this.food.count = this.count;
            }
        }
    };
</script>

以下是shopcart.vue

<template>
    <div class="shopcart">
        <div class="content">
            <div class="content-left">
                <div class="logo-wrapper">
                    <div class="logo" :class="{'hasFoods':totalCount!=0}">
                        <i class="icon-shopping_cart"></i>
                    </div>
                    <div class="number" v-show="totalCount>0">{{totalCount}}</div>
                </div>
                <div class="price" :class="{'select-price':totalCount>0}">¥{{totalPrice}}</div>
                <div class="desc" v-show="lessThanDeliPrice>=0">另需配送费¥{{deliveryPrice}}</div>
            </div>
            <div class="content-right">
                <div class="pay" v-show="totalCount==0">¥{{minPrice}}起送</div>
                <div class="lessThanToDelivery" v-show="lessThanDeliPrice>0">还差¥{{lessThanDeliPrice}}配送</div>
                <div class="goPay" v-show="totalPrice>=minPrice">去结算</div>
            </div>
        </div>
    </div>
</template>

<script type="text/ecmascript-6">
    export default {
        props: {
            selectFoods: {
                type: Array,
                default () {
                    return [];
                }
            },
            deliveryPrice: {
                type: Number,
                default: 0
 },
            minPrice: {
                type: Number,
                default: 0
 }
        },
        computed: {
            totalPrice () {
                let total = 0;
                console.log(this.selectFoods);
                this.selectFoods.forEach((food) => {
                    total += food.price * food.count;
                });
                return total;
            },
            totalCount () {
                let count = 0;
                this.selectFoods.forEach((food) => {
                    count += food.count;
                });
                return count;
            },
            lessThanDeliPrice () {
                return this.minPrice - this.totalPrice;
            },
            minPriceShow () {
                return this.lessThanDeliPrice < 0;
            }
        }
    };
</script>

以下是goods.vue

<template>
    <div class="goods">
        <div class="menu-wrapper" ref="menuWrapper">
            <ul>
                <li v-for="(item,index) in goods" class="border-1px menu-item menu-item-hook"
                    :class="{'active-menu':index==currentIndex}" @click="clickMenu(index,$event)">
                    <span class="text">
                        <span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>
                        {{item.name}}
                    </span>
                </li>
            </ul>
        </div>
        <div class="foods-wrapper" ref="foodsWrapper">
            <ul>
                <li v-for="item in goods" class="food-list  food-list-hook">
                    <h1 class="title">{{item.name}}</h1>
                    <ul>
                        <li v-for="(food,index) in item.foods" class="food-item border-1px">
                            <div class="icon">
                                <img width="57" height="57" :src="food.icon" alt="icon">
                            </div>
                            <div class="content">
                                <h2 class="name">{{food.name}}</h2>
                                <p class="description">{{food.description}}</p>
                                <span class="sellCount">月售{{food.sellCount}}份</span>
                                <span class="rate">好评率{{food.rating}}%</span>
                                <div class="price-buy">
                                    <span class="now-price">¥{{food.price}}</span>
                                    <span class="old-price" v-show="food.oldPrice">¥{{food.oldPrice}}</span>
                                </div>
                            </div>
                            <div class="cartControl-wrapper">
                                <cartcontrol :food="food"></cartcontrol>
                            </div>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
        <shopcart :selectFoods="selectFoods" :deliveryPrice="seller.deliveryPrice"
                  :minPrice="seller.minPrice"></shopcart>
    </div>
</template>

<script type="text/ecmascript-6">
    import BSroll from 'better-scroll';
    import shopcart from '../../components/shopcart/shopcart.vue';
    import cartcontrol from '../../components/cartcontrol/cartcontrol.vue';
    const ERR_OK = 0;
    export default {
        data () {
            return {
                goods: [],
                foodsHeight: [],
                menuHeight: [],
                scrollY: 0
            };
        },
        props: {
            seller: {
                type: Object
            }
        },
        created () {
            this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
            this.$http.get('/api/goods').then(response => {
                response = response.body;
                if (response.errno === ERR_OK) {
                    this.goods = response.data;
                    this.$nextTick(() => {
                        this._initScroll();
                        this._caculateHeight();
                    });
                }
            });
        },
        computed: {
            currentIndex () {
                for (let i = 0, iLen = this.foodsHeight.length; i < iLen; i++) {
                    if (this.scrollY < this.foodsHeight[i]) {
                        this.currentIndex = i;
                        return i;
                    }
                }
            },
            selectFoods () {
                let foods = [];
                this.goods.forEach((good) => {
                    good.foods.forEach((food) => {
                        if (food.count) {
                            foods.push(food);
                        }
                    });
                });
                return foods;
            }
        },
        methods: {
            clickMenu (index, event) {
                if (!event._constructed) {
                    return;
                }
                let foodsWrapper = this.$refs.foodsWrapper;
                let foodsList = foodsWrapper.getElementsByClassName('food-list-hook');
                let el = foodsList[index];
                this.foodsScroll.scrollToElement(el, 100);
            },
            _initScroll () {
                this.menuScroll = new BSroll(this.$refs.menuWrapper, {
                    click: true
                });
                this.foodsScroll = new BSroll(this.$refs.foodsWrapper, {
                    probeType: 3,
                    click: true
                });
                this.foodsScroll.on('scroll', (pos) => {
                    this.scrollY = Math.abs(Math.round(pos.y));
                });
            },
            _caculateHeight () {
                let foodsWrapper = this.$refs.foodsWrapper;
                let foodsList = foodsWrapper.getElementsByClassName('food-list-hook');
                let height = 0;
                for (let i = 0, iLen = foodsList.length; i < iLen; i++) {
                    height += foodsList[i].clientHeight;
                    this.foodsHeight.push(height);
                }
            }
        },
        components: {
            shopcart,
            cartcontrol
        }
    };
</script>


写回答

1回答

MorningDuGe

提问者

2017-05-17

明白了  只有当Vue.set时才会更新,所以将cartcontrol中的methods里边的方法改为

methods: {
    addCart (event) {
        if (!event._constructed) {
            return;
        }
        if (!this.food.count) {
            Vue.set(this.food, 'count', 1);
            this.count = 1;
        } else {
            Vue.delete(this.food, 'count');
            this.count++;
            Vue.set(this.food, 'count', this.count);
        }
    },
    removeCart (event) {
        if (!event._constructed) {
            return;
        }
        Vue.delete(this.food, 'count');
        this.count--;
        Vue.set(this.food, 'count', this.count);
    }
}


0
0

Vue.js2.5+cube-ui重构饿了么App(经典再升级)

掌握Vue1.0到2.0再到2.5最全版本应用与迭代,打造极致流畅的WebApp

9868 学习 · 4162 问题

查看课程