image-swiper.vue 5.99 KB
<template>
    <div class="image-swipe" v-if="allLoaded">
        <div class="swipe-wrap" @click.prevent="showcase()">
            <swiper :options="swiperOption" ref="swiper">
                <swiper-slide v-for="item in goodsList" :key="item.title">
                    <img :title="item.title"
                         v-img-src="{src: item.color_image, width: 580, height: 770}"
                         width="100%">
                </swiper-slide>
            </swiper>
        </div>
        <div class="pagination-wrapper">
            <ul class="page-items">
                <li v-for="index in slideCount" :key="index" class="page-item"
                    :class="{active: index - 1 == activeIndex}"></li>
            </ul>
        </div>
    </div>
</template>
<script>
    require('swiper/dist/css/swiper.css');
    import yoho from 'yoho';
    import util from 'common/util';
    import vas from 'vue-awesome-swiper';

    export default {
        props: {
            goods: [Array]
        },
        data() {
            let vm = this;

            return {
                slideCount: 0,
                activeIndex: 0,
                goodsList: [],
                swiperOption: {
                    loop: true,
                    slidesPerView: 3,
                    onSlideChangeEnd(swiper) {
                        vm.setActiveSlide(swiper.realIndex)
                    }
                },
                allLoaded: false
            };
        },
        components: {
            swiper: vas.swiper,
            swiperSlide: vas.swiperSlide,
            notNextTick: true
        },
        computed: {
            swiper() {
                return this.$refs.swiper.swiper;
            }
        },
        watch: {
            goods(val) {
                let temp = val.slice();
                const len = temp.length;

                if (len > 1 && len < 4) {
                    temp.unshift(temp.splice(len - 1)[0]);
                }

                if (len >= 4) {
                    const sp = temp.splice(0, 2);

                    temp.push(sp[0]);
                    temp.push(sp[1]);
                }
                this.goodsList = temp;
                this.slideCount = this.goodsList.length;
            },
            goodsList(goods) {
                const preloadImg = (list, loaded) => {
                    loaded = loaded || [];

                    // 加载完成
                    if(list.length === 0) {
                        let $ssr = document.getElementById('ssr');
                        $ssr && $ssr.remove();
                        this.allLoaded = true;
                        return;
                    }

                    let img = new Image();
                    img.src = util.getImgUrl(list[0].image_url, '580', '770');

                    if(img.complete) {
                        loaded.push(img);
                        list.shift();
                        preloadImg(list, loaded);
                    }
                    else {
                        img.onload = function() {
                            loaded.push(img);
                            list.shift();
                            preloadImg(list, loaded);
                        };
                    }
                };

                preloadImg(goods[0].images_list);
            }
        },
        methods: {
            showcase: function() {
                const realIndex = this.swiper.realIndex;
                const index = this.calcIndex(realIndex);

                const opts = {
                    index,
                    images: this.goods.map((item) => {
                        return item.color_image;
                    }).filter(image => image),
                };

                yoho.goImageBrowser(opts);
            },
            setActiveSlide(idx){
                this.activeIndex = this.calcIndex(idx);
            },
            calcIndex(realIdx){
                const len = this.goods.length;

                if (len >= 4) {
                    if (realIdx === len -1) {
                        realIdx = 0;
                    } else {
                        realIdx += 1;
                    }

                    if (realIdx < len -2) {
                        realIdx += 2;
                    } else if (realIdx === len -2) {
                        realIdx = 0;
                    } else {
                        realIdx = 1;
                    }
                }

                return realIdx;
            }
        }
    };
</script>
<style>


#ssr {
    .ssr-swiper-container {
        height: 770px;
        background-color: #f7f7f7;
    }
    .ssr-swiper {
        width: 620px;
        height: 770px;
        padding: 0 20px;
        background-color: #fff;
        transform: translateX(590px);
        font-size: 0;

        img {
            width: 580px;
            height: 770px;
        }
    }

    .show-box.carousel {
        border-top: none;
        border-bottom: none;
    }
    .show-box.info,
    .show-box.action {
        border-top: none;
    }

    .show-box.action {
        padding-bottom: 0;
        border-bottom: none;
    }
}

.image-swipe {
    position: relative;
    overflow: hidden;

    .swipe-wrap {
        height: 770px;
        width: 1800px;
        transform: translateX(-520px);
    }

    .swiper-slide {
        width: 600px;
        height: 770px;
        padding: 0 10px;
    }
    .swiper-container {
        overflow: visible;
    }

    .pagination-wrapper {
        position: absolute;
        bottom: 0;
        left: 50%;
        height: 60px;
        text-align: center;
        transform: translateX(-50%);

        .page-items {
            top: 12px;
            left: 50%;
            line-height: 55px;
        }

        .page-item {
            display: inline-block;
            width: 10px;
            height: 10px;
            margin: 0 5px;
            border-radius: 0;
            background-color: #b0b0b0;
        }

        .page-item.active {
            width: 20px;
            background-color: #000;
        }
    }
}
</style>