uniapp 展示多个轮播图

249 阅读4分钟
<swiper class="scroll" style=" height: 280px" previous-margin="100rpx" next-margin="100rpx" :current="currentIndex" :autoplay="true" :circular="true" @change="swiperChange"  @animationfinish="animationfinish">
    <swiper-item v-for="(item, index) in list" :key="index" @click="toDetail(item)">
        <view class="swiper-flex-item" :style="{
                'align-items':
                    (currentIndex == index && !isChange) || (indexParse(1) == index && isChange)
                        ? 'center'
                        : (indexParse(1) == index && !isChange) || (indexParse(2) == index && isChange)
                        ? 'flex-start'
                        : ''
            }">
            <view :class="['swiper-image', currentIndex == index ? 'active-image' : '']" :style="{
                    height: currentIndex == index ? activeImageHeight + 'px' : activeImageHeight * 0.9 + 'px',
                    width: currentIndex == index ? '' : activeImageHeight * 0.9 + 'px',
                    'margin-top': currentIndex == index ? 0 : activeImageHeight * 0.05 + 'px'
                }">
                <view :class="currentIndex == index ? '' : 'swiper-mask'"></view>
            </view>
        </view>
    </swiper-item>
</swiper>

data() {
    return {
        list: ["", "", "", "", ""],
        currentIndex: 0,
        activeImageHeight: 200,
        isChange: false
    }
},
methods: {
    swiperChange() {
        this.isChange = true;
    },
    animationfinish(e) {
        this.currentIndex = e.detail.current;
        this.isChange = false;
    },
    indexParse(index) {
        return parseInt((this.currentIndex + index + this.list.length) % this.list.length);
    }
}

.swiper-flex-item {
    margin-top: 7px;
    border-radius: 20rpx;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;

    .swiper-image {
        width: 100%;
        border-radius: 20rpx;
        transition: height 0.5s;
        background: red;
        position: relative;
        background-repeat: no-repeat;
    }

    .swiper-mask {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 10000;
        border-radius: 20rpx;
        background: rgba(255, 255, 255, 0.6);
    }

    .active-image {
        width: 60%;
    }
}

image.png

<template>
    <view class="home">
        <view class="home-module">
            <image class="home-module-bg" :src="渐变背景图" mode="widthFix"></image>
            <view class="swiper" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
                <view :class="{'left-current':1==status,'left-right':2==status}" class="left-item"
                    @click="indexChange(leftIndex)">
                    <view class="flex-column-center ">
                        <image class="logo" :src="$util.img(modules[leftIndex].img)">
                        </image>
                        <view>{{modules[leftIndex].title}}</view>
                    </view>
                </view>
                <view class="current-item"
                    :class="{'current-right':1==status,'current-left':2==status,'active':0===status}">
                    <view class="flex-column-center">
                        <image class="logo"
                            :src="$util.img(0==status ? modules[currentIndex].imgActive:modules[currentIndex].img)">
                        </image>
                        <view>{{modules[currentIndex].title}}</view>
                    </view>
                </view>
                <view class="right-item" :class="{'right-left':1==status,'right-current':2==status}"
                    @click="indexChange(rightIndex)">
                    <view class="flex-column-center ">
                        <image class="logo" :src="$util.img(modules[rightIndex].img)">
                        </image>
                        <view>{{modules[rightIndex].title}}</view>
                    </view>
                </view>
            </view>
            <view class="content">
                <swiper :style="{height:contentHeight}" circular :current="currentIndex" @change="swiperChange">
                    <swiper-item>
                        <view class="item">
                            index=0的内容
                        </view>
                    </swiper-item>
                    <swiper-item>
                        <view class="item">
                            index=1的内容
                        </view>
                    </swiper-item>
                    <swiper-item>
                        <view class="item">
                            index=2的内容
                        </view>
                    </swiper-item>
                    <swiper-item>
                        <view class="item">
                            index=3的内容
                        </view>
                    </swiper-item>
                    <swiper-item>
                        <view class="item">
                            index=4的内容
                        </view>
                    </swiper-item>
                </swiper>
            </view>
        </view>
    </view>
</template>

<script>
    const MAPS = [{
            title: 'xxx0',
            img: '图标',
            imgActive: '高亮图标'
        },
        {
            title: 'xxx1',
            img: '图标',
            imgActive: '高亮图标'
        },
        {
            title: 'xxx2',
            img: '图标',
            imgActive: '高亮图标'
        },
        {
            title: 'xxx3',
            img: '图标',
            imgActive: '高亮图标'
        },
        {
            title: 'xxx4',
            img: '图标',
            imgActive: '高亮图标'
        }
    ];
    export default {
        data() {
            return {
                modules: MAPS,
                status: 0,
                leftIndex: 0,
                rightIndex: 2,
                currentIndex: 1,
                bannerIndex: 0,
                contentHeight: ''
            }
        },
        onShow() {
            this.getInfo();
        },
        methods: {
            // 获取swiper高度
            initConentHeight() {
                setTimeout(() => {
                    uni.createSelectorQuery()
                        .in(this)
                        .select('.item')
                        .boundingClientRect(data => {
                            if (data) {
                                this.contentHeight = data.height + 'px'
                            }
                        })
                        .exec();
                }, 100)
            },
            getInfo() {
                // 根据需要判断是否需要调用接口
                this.initConentHeight()
            },
            swiperChange(e) {
                this.indexChange(e.detail.current)
            },
            touchStart(event) {
                // 记录触摸起始点的横坐标
                this.startX = event.touches[0].clientX;
            },
            touchMove(event) {
                // 计算滑动距离
                const currentX = event.touches[0].clientX;
                const deltaX = currentX - this.startX;
                // 判断滑动方向
                if (deltaX > 30) {
                    this.status = 1
                } else if (deltaX < -30) {
                    this.status = 2
                }
            },
            touchEnd() {
                if (1 === this.status) {
                    this.currentIndex = 0 === this.currentIndex ? this.modules.length - 1 : this.currentIndex - 1;
                } else if (2 === this.status) {
                    this.currentIndex = this.currentIndex === this.modules.length - 1 ? 0 : this.currentIndex + 1
                }
                this.getInfo()
                setTimeout(() => {
                    this.status = 0
                    this.leftIndex = 0 === this.currentIndex ? this.modules.length - 1 : this.currentIndex - 1
                    this.rightIndex = this.currentIndex === this.modules.length - 1 ? 0 : this.currentIndex + 1
                }, 500)
            },
            indexChange(current) {
                if (this.currentIndex !== current) {
                    this.status = ((this.currentIndex > current && !(this.modules
                        .length - 1 === this.currentIndex && 0 === current)) || (0 === this
                        .currentIndex && this.modules
                        .length - 1 === current)) ? 1 : 2
                    this.currentIndex = current
                    this.getInfo()
                    setTimeout(() => {
                        this.status = 0
                        this.leftIndex = 0 === this.currentIndex ? this.modules.length - 1 : this.currentIndex -
                            1
                        this.rightIndex = this.currentIndex === this.modules.length - 1 ? 0 : this
                            .currentIndex + 1
                    }, 500)
                }
            }
        }
    }
</script>

<style lang="scss" scoped>
    .home {
        position: relative;

        &-module {
            position: relative;

            &-bg {
                width: 100%;
                margin-top: 120rpx;
            }

            .swiper {
                width: 100%;
                position: absolute;
                top: 50rpx;
                left: 0;

                .logo {
                    width: 122rpx;
                    height: 122rpx;
                }

                view {
                    color: #8494CF;
                    font-size: 30rpx;
                    font-weight: 600;
                }

                .active {
                    view {
                        color: #fff;
                    }
                }

                .current-item,
                .left-item,
                .right-item {
                    width: 33.34%;
                    height: 200rpx;
                }

                .current-item {
                    position: absolute;
                    top: 0;
                    left: 33.34%;
                }

                .current-right {
                    animation: currentRight 0.5s linear forwards;

                    @keyframes currentRight {
                        0% {
                            top: 0;
                            left: 50%;
                            transform: rotate(0deg);
                        }

                        100% {
                            top: 50rpx;
                            left: 68%;
                            transform: rotate(25deg);
                        }
                    }
                }

                .current-left {
                    animation: currentLeft 0.5s linear forwards;

                    @keyframes currentLeft {
                        0% {
                            top: 0;
                            left: 50%;
                            transform: rotate(0deg);
                        }

                        100% {
                            top: 50rpx;
                            left: 0;
                            transform: rotate(-25deg);
                        }
                    }
                }

                .left-item {
                    position: absolute;
                    top: 50rpx;
                    left: 0;
                    transform: rotate(-25deg);
                }

                .left-current {
                    animation: leftCurrent 0.5s linear forwards;

                    @keyframes leftCurrent {
                        0% {
                            top: 50rpx;
                            left: 0;
                            transform: rotate(-25deg);
                        }

                        100% {
                            top: 0;
                            left: 33.34%;
                            transform: rotate(0deg);
                        }
                    }
                }

                .left-right {
                    animation: leftHide 0.5s linear forwards, rightShow 0.3s linear forwards 0.25s;

                    @keyframes leftHide {
                        0% {
                            top: 50rpx;
                            left: 0;
                            transform: rotate(-25deg);
                        }

                        100% {
                            top: 100rpx;
                            left: -20%;
                            transform: rotate(0deg);
                            opacity: 0;
                        }
                    }

                    @keyframes rightShow {
                        0% {
                            top: 100rpx;
                            left: 100%;
                            transform: rotate(0deg);
                            opacity: 0;
                        }

                        100% {
                            top: 50rpx;
                            left: 68%;
                            transform: rotate(25deg);
                            opacity: 1;
                        }
                    }
                }

                .right-item {
                    position: absolute;
                    top: 50rpx;
                    left: 68%;
                    transform: rotate(25deg);
                }

                .right-left {
                    animation: rightHide 0.5s linear forwards, leftShow 0.3s linear forwards 0.25s;

                    @keyframes rightHide {
                        0% {
                            top: 50rpx;
                            left: 68%;
                            transform: rotate(25deg);
                        }

                        100% {
                            top: 100rpx;
                            left: 100%;
                            transform: rotate(0deg);
                            opacity: 0;
                        }
                    }

                    @keyframes leftShow {
                        0% {
                            top: 100rpx;
                            left: -33.34%;
                            transform: rotate(0deg);
                            opacity: 0;
                        }

                        100% {
                            top: 50rpx;
                            left: 0;
                            transform: rotate(-25deg);
                            opacity: 1;
                        }
                    }
                }

                .right-current {
                    animation: rightCurrent 0.5s linear forwards;

                    @keyframes rightCurrent {
                        0% {
                            top: 50rpx;
                            left: 68%;
                            transform: rotate(25deg);
                        }

                        100% {
                            top: 0;
                            left: 33.34%;
                            transform: rotate(0deg);
                        }
                    }
                }
            }

            .content {
                width: calc(99.9% - 60rpx);
                min-height: 240px;
                position: absolute;
                top: 380rpx;
                left: 30rpx;

                .share-img {
                    width: 99.9%;
                    overflow: hidden;
                    border-radius: 30rpx;
                }

                .item {
                    background-color: #fff;
                    border-radius: 30rpx;
                    padding: 30rpx;
                }

                button {
                    width: 50%;
                    margin: 0 auto;
                }
            }

            .empty {
                padding: 80rpx 0 50rpx;
            }
        }

    }
</style>

image.png

一个个切换

<swiper class="swiper flex-align" autoplay="true" :interval="1000" :current="currentIndex"
                    :circular="true" @animationfinish="swiperChange">
    <swiper-item class="swiper-item" v-for="(item, index) in prizes" :key="index"
        @click="toDetail(item)">
        <image class="swiper-image" :src="item.thumbnail_image" mode="aspectFit"></image>
    </swiper-item>
</swiper>

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6286f54a147a4ecea1d04fce8a47c08e~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=472&h=967&s=68949&e=png&b=f5f7f8)
swiperChange(e) {
    this.currentIndex = e.detail.current;
}

/deep/ swiper-item {
    width: 130rpx !important;
    padding-right: 20rpx !important;
}
.swiper {
    height: 130rpx;

    .swiper-item {
        border-sizing: border-box;

        .swiper-image {
            width: 130rpx;
            height: 130rpx;
            border-radius: 20rpx;
        }
    }
}
                

效果图:

image.png

动画从左向右滚动

<view class="image-animation">
    <view class="item">
        <view class="swiper-image" v-for="(item,index) in prizes" :key="index">
            <image :src="item.thumbnail_image" mode="aspectFit"></image>
        </view>
    </view>
</view>

.image-animation {
    width: 100%;
    height: 130rpx;
    white-space: nowrap;
    position: relative;
    overflow: hidden;

    .item {
        position: absolute;
        animation: imageGif 15s linear infinite;

        .swiper-image {
            display: inline-block;
            margin-right: 20rpx;

            image {
                position: relative;
                display: inline-block;
                width: 130rpx;
                height: 130rpx;
                border-radius: 20rpx;
            }
        }

        @keyframes imageGif {
            0% {
                transform: translateX(0);
            }

            100% {
                transform: translateX(-100%);
            }
        }
    }
}

效果图:

image.png

更多:ext.dcloud.net.cn/plugin?id=7…