add-to-cart.vue 7.11 KB
<template>
<div class="add-cart" :class="cartClass">
    <ul class="cart-detail">
        <li v-touch:tap="pickColor">
            <span class="color">{{colorName || '颜色'}}</span>
            <i class="icon color" :class="sortClass('color')"></i>
        </li>
        <li v-touch:tap="pickSize">
            <span class="size">{{sizeName || '尺码'}}</span>
            <i class="icon size" :class="sortClass('size')"></i
        </li>
    </ul>
    <a class="add-btn" v-touch:tap="toCart">{{buttonText}}</a>
    <slide-select v-ref:slideSelect
        :slides="slideList"
        :model="slideId"
        :title="slideTitle"
        :tag="slideTag"
        @selected="slideSelect"
        @hide="slideHide"></slide-select>
</div>
</template>

<script>
const slideSelect = require('./slide-select.vue');
const tip = require('common/tip');

module.exports = {
    name: 'add-to-cart',
    props: {
        value: {
            type: Object,
            default() {
                return {};
            }
        }
    },
    data() {
        return {
            skuList: [],
            slideList: [],
            slideTitle: '',
            slideId: 0,
            slideTag: '',
            colorName: '',
            sizeName: '',
            colorId: 0,
            sizeId: 0,
            sku: 0,
        };
    },
    computed: {
        cartClass() {
            if (this.value.storage_sum <= 0) {
                return {'no-storage': true};
            }
            return {};
        },
        buttonText() {
            if (this.value.storage_sum <= 0) {
                return '已售罄';
            }
            return '加入购物车';
        }
    },
    methods: {
        sortClass(tag) {
            if (this.slideTag === tag) {
                return {'icon-sort-up': true};
            }
            if (this.slideTag === tag) {
                return {'icon-sort-up': true};
            }
            return {'icon-sort-down': true};
        },
        pickColor() {
            if (this.skuList.length && this.value.storage_sum > 0) {
                let slides = [];

                this.skuList.filter(sku => sku.storage).forEach(sku => {
                    if (!slides.some(slide => slide.id === sku.colorId)) {
                        slides.push({
                            text: sku.colorName,
                            id: sku.colorId
                        });
                    }
                });
                this.slideList = slides;
                this.slideId = this.colorId;
                this.slideTitle = '颜色';
                this.slideTag = 'color';
                this.$refs.slideselect.show();
            }
        },
        pickSize() {
            if (this.skuList.length && this.value.storage_sum > 0) {
                let slides = [];

                this.skuList.filter(sku => sku.storage).forEach(sku => {
                    if (!slides.some(slide => slide.id === sku.sizeId) &&
                        (!this.colorId || sku.colorId === this.colorId)) {
                        slides.push({
                            text: sku.sizeName,
                            id: sku.sizeId
                        });
                    }
                });
                this.slideList = slides;
                this.slideId = this.sizeId;
                this.slideTitle = '尺码';
                this.slideTag = 'size';
                this.$refs.slideselect.show();
            }
        },
        slideSelect(params) {
            if (params.tag === 'color') {
                this.colorId = params.slide.id;
                this.colorName = params.slide.text;
                this.sizeId = 0;
                this.sizeName = '';
            } else {
                this.sizeId = params.slide.id;
                this.sizeName = params.slide.text;
            }
        },
        processSku(goodsList) {
            let skus = [];

            goodsList.filter(color => color.status).forEach(color => {
                color.size_list.filter(size => size.status).forEach(size => {
                    if (!skus.some(sku => sku.colorId === color.color_id && sku.sizeId === size.size_id)) {
                        skus.push({
                            colorId: color.color_id,
                            colorName: color.factory_goods_name,
                            sizeId: size.size_id,
                            sizeName: size.size_name,
                            sku: size.product_sku,
                            storage: size.storage_number,
                        });
                    }
                });
            });
            return skus;
        },
        toCart() {
            if (this.value.storage_sum <= 0) {
                return;
            }
            if (!this.colorId) {
                return tip('请选择颜色');
            }
            if (!this.sizeId) {
                return tip('请选择尺码');
            }
            let sku = this.skuList.find(s => s.colorId === this.colorId && s.sizeId === this.sizeId);

            if (sku) {
                this.reset();
                this.$emit('add-cart', sku);
            }
        },
        slideHide() {
            this.slideTag = '';
        },
        reset() {
            this.colorName = '';
            this.sizeName = '';
            this.colorId = 0;
            this.sizeId = 0;
        },
    },
    watch: {
        value(val) {
            if (val) {
                this.skuList = this.processSku(val.goods_list);
            }
        }
    },
    components: {slideSelect}
};
</script>

<style>
.add-cart {
    &.no-storage {
        .cart-detail {
            color: #b0b0b0;

            .icon {
                display: none;
            }
        }

        .add-btn {
            background-color: #b0b0b0;
            border-color: #b0b0b0;
        }
    }

    .cart-detail {
        font-size: 0;
        height: 100px;
        margin-bottom: 40px;
        border-top: 1px solid #eee;
        border-bottom: 1px solid #eee;
        display: flex;

        li {
            position: relative;
            display: flex;
            line-height: 100px;
            height: 100px;
            overflow: hidden;
            font-size: 32px;
            flex: 1 1 100%;
            align-items: center;
            justify-content: space-between;

            .icon {
                float: right;
                font-weight: bold;
                font-size: 40px;

                &.icon-sort-down {
                    margin-top: -15px;
                }
            }

            span {
                display: block;
                height: 40px;
                line-height: 40px;
            }

            &:first-child {
                padding-right: 30px;
            }

            &:last-child {
                span {
                    padding-left: 30px;
                    border-left: solid 1px #e0e0e0;
                }
            }
        }
    }

    .add-btn {
        display: inline-block;
        width: 100%;
        height: 85px;
        color: #fff;
        font-size: 32px;
        text-align: center;
        line-height: 82px;
        background-color: #000;
        border: 1px solid #7a7a7a;
    }
}
</style>