美文网首页
Vue Swiper 水平轮播--简陋版

Vue Swiper 水平轮播--简陋版

作者: R_X | 来源:发表于2022-04-12 17:17 被阅读0次

1、index.vue

<template>
    <div class="page-content">
        <swiper :autoPlay="false">
            <swiper-item v-for="i in 4" :key="i">
                <div
                    class="cust"
                    :style="{
                        backgroundColor: `#${colors[i - 1]}`
                    }"
                >{{i}}</div>
            </swiper-item>
        </swiper>
    </div>
</template>
<script>
import swiper from './swiper.vue';
import swiperItem from './swiper-item.vue';
export default {
    name: 'Announcement',
    components: {
        swiper,
        swiperItem
    },
    data() {
        return {
            colors: ['e71dba', '87eb86', 'e14723', 'd3d72f']
        };
    }
};
</script>
<style lang="less" scoped>
    .page-content {
        display: flex;
        justify-content: center;
        .cust {
            text-align: center;
            border: 1px solid;
            width: 400px;
            height: 300px;
            line-height: 300px;
        }
    }
</style>

2、swiper.vue

<template>
    <div class="swiper-content" :style="{
        height: `${height}px`,
        width: `${width}px`
    }">
        <div @click="clickHandle('pre')" class="swiper-btn-content swiper-btn-content_left">
            <slot name="leftBtn">
                <div class="swiper-btn left-btn"></div>
            </slot>
        </div>
        <div @click="clickHandle('next')" class="swiper-btn-content swiper-btn-content_right">
            <slot name="rightBtn">
                <div class="swiper-btn right-btn"></div>
            </slot>
        </div>
        <slot></slot>
    </div>
</template>
<script>
export default {
    name: 'swiper',
    props: {
        height: {
            type: Number,
            default: 300
        },
        width: {
            type: Number,
            default: 400
        },
        intervalTime: {
            type: Number,
            default: 1500
        },
        autoPlay: {
            type: Boolean,
            default: true
        }
    },
    data() {
        return {
            changeType: '',
            active: 0,
            interval: null,
            slotsLength: 0
        };
    },
    mounted() {
        if (this.$slots && this.$slots.default) {
            this.slotsLength = this.$slots.default.length;
            this.initSwiper(this.active);
            if (this.autoPlay) {
                this.interval = setInterval(() => {
                                        this.changeType = 'next';
                    if (this.active >= this.slotsLength - 1) {
                        this.active = 0;
                    } else {
                        this.active++;
                    }
                }, this.intervalTime);
            }
        }
    },
    destroyed() {
        if (this.autoPlay) {
            clearInterval(this.interval);
        }
    },
    watch: {
        active(val) {
            this.initSwiper(val);
        }
    },
    methods: {
        initSwiper(active) {
            for (let i = 0, s = this.$slots.default; i < s.length; i++) {
                s[i].elm.style.transition = '';
                if (i === active + 1) { // 此时将要展示的item的后一个
                    if (this.changeType === 'pre') {
                        s[i].elm.style.transition = 'transform .5s ease-in-out';
                    }
                    s[i].elm.style.transform = `translateX(${this.width}px) scale(1)`;
                } else if (i === active - 1) { // 此时将要展示的item的前一个
                    s[i].elm.style.transition = 'transform .5s ease-in-out';
                    s[i].elm.style.transform = `translateX(-${this.width}px) scale(1)`;
                } else if (active === s.length - 1 && i === s.length - 1) { // 当前展示:最后一个item
                    s[0].elm.style.transform = `translateX(${this.width}px) scale(1)`;
                    s[i].elm.style.transition = 'transform .5s ease-in-out';
                    s[i].elm.style.transform = `translateX(0px) scale(1)`;
                } else if (i !== active + 1 && i !== active - 1 && i !== active) { //其他 不等于当前展示的item
                    if (!active && i === s.length - 1) { // 当前展示:第一个item,则需要对最后一个进行特殊设置
                        s[s.length - 1].elm.style.transition = 'transform .5s ease-in-out';
                        s[s.length - 1].elm.style.transform = `translateX(-${this.width}px) scale(1)`; // 最后一个item
                    } else if (active === s.length - 1 && !i) { // 如果是 倒序轮播时,此时将要展示的是最后一个, 第一个item即将向右隐藏时
                        s[0].elm.style.transition = 'transform .5s ease-in-out';
                        s[0].elm.style.transform = `translateX(${this.width}px) scale(1)`;
                    } else {
                        s[i].elm.style.transform = `translateX(-${this.width * (s.length - 1)}px) scale(1)`;
                    }
                } else {
                    s[i].elm.style.transition = 'transform .5s ease-in-out';
                    s[i].elm.style.transform = `translateX(0px) scale(1)`;
                }
            }
        },
        clickHandle (type) {
            if (type === 'pre') {
                this.changeType = 'pre';
                if (this.active > 0) {
                    this.active--;
                } else {
                    this.active = this.slotsLength - 1;
                }
            } else {
                this.changeType = 'next';
                if (this.active < this.slotsLength - 1) {
                    this.active++;
                } else {
                    this.active = 0;
                }
            }
        }
    }
};
</script>
<style lang="less" scoped>
    .swiper-content {
        position: relative;
        overflow: hidden;
        .swiper-btn-content {
            position: absolute;
            min-width: 36px;
            min-height: 36px;
            z-index: 9;
            transform: translateY(-50%);
            top: 50%;
            .swiper-btn {
                position: absolute;
                display: flex;
                justify-content: center;
                align-items: center;
                width: 36px;
                height: 36px;
                color: #FFFFFF;
                font-size: 12px;
                cursor: pointer;
                border-radius: 50%;
                background-color: rgba(31, 45, 61, .11);
                transition: .5s;
                &:hover {
                    background-color: rgba(31, 45, 61, .34);
                }
            }
            .left-btn {
                left: 5px;
                &::before {
                    content: '<';
                }
            }
            .right-btn {
                right: 5px;
                &::before {
                    content: '>';
                }
            }
            &_left {
                left: 5px;
            }
            &_right {
                right: 5px;
            }
        }
    }
</style>

3、swiper-item.vue

<template>
    <div class="item">
        <slot></slot>
    </div>
</template>
<script>
export default {
    name: 'swiperItem'
};
</script>
<style lang="less" scoped>
    .item {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
    }
</style>

相关文章

网友评论

      本文标题:Vue Swiper 水平轮播--简陋版

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