uni-app实现swiper滑动放大缩小、实现scroll-view与swiper双向联动

@高效码农  May 30, 2022

uni-app实现swiper滑动放大缩小、实现scroll-view与swiper双向联动

先看效果图

在这里插入图片描述

思路

1、利用scroll-view的scroll-into-view属性:值为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
2、利用swiper的current属性:当前所在滑块的 index

布局代码

<template>
    <view>
        <scroll-view class="scroll-top" scroll-x="true" show-scrollbar="false" :scroll-into-view="seqToView">
            <view class="scroll-view-item" v-for="(item,index) in list" :id="'seq-' + index" @click="tabClick(index)">
                <view class="scroll-view-item-view">
                    <image class="scroll-top-item-image" :src="item.image"></image>
                    <text class="scroll-top-item-text">{{item.title}}</text>
                </view>
            </view>
        </scroll-view>

        <swiper class="swiper-top" previous-margin='28px' next-margin='28px' @change="change" :current="currentIndex">
            <block v-for="(item,index) in swiperList" :key="index">
                <swiper-item>
                    <view class="box" :animation="index == currentIndex?animationData:animationData2">
                        <view class="imgcot">
                            <image :src="item.image" mode="widthFix"></image>
                        </view>
                    </view>
                </swiper-item>
            </block>
        </swiper>

    </view>
</template>

完整代码

<template>
    <view>
        <scroll-view class="scroll-top" scroll-x="true" show-scrollbar="false" :scroll-into-view="seqToView">
            <view class="scroll-view-item" v-for="(item,index) in list" :id="'seq-' + index" @click="tabClick(index)">
                <view class="scroll-view-item-view">
                    <image class="scroll-top-item-image" :src="item.image"></image>
                    <text class="scroll-top-item-text">{{item.title}}</text>
                </view>
            </view>
        </scroll-view>

        <swiper class="swiper-top" previous-margin='28px' next-margin='28px' @change="change" :current="currentIndex">
            <block v-for="(item,index) in swiperList" :key="index">
                <swiper-item>
                    <view class="box" :animation="index == currentIndex?animationData:animationData2">
                        <view class="imgcot">
                            <image :src="item.image" mode="widthFix"></image>
                        </view>
                    </view>
                </swiper-item>
            </block>
        </swiper>

    </view>
</template>

<script>
    export default {
        data() {
            return {
                list: [
                    {
                        image: '/static/image/member/es0-selected.png',
                        title: '海关数据系统\n多账号免费用'
                    },
                    {
                        image: '/static/image/member/es1-unselect.png',
                        title: '建站推广服务\n抵用券'
                    },
                    {
                        image: '/static/image/member/es2-unselect.png',
                        title: '企业网站免费\n诊断1次'
                    }, {
                        image: '/static/image/member/es3-unselect.png',
                        title: '海外广告投放\n免费开'
                    }, {
                        image: '/static/image/member/es4-unselect.png',
                        title: '2CShop独立\n站商城试用'
                    }, {
                        image: '/static/image/member/es5-unselect.png',
                        title: '提供优质服务\n商产品折扣'
                    }
                ],
                swiperList: [
                    {
                        image: '/static/image/member/es0.png'
                    },
                    {
                        image: '/static/image/member/es1.png'
                    },
                    {
                        image: '/static/image/member/es2.png'
                    }, 
                    {
                        image: '/static/image/member/es3.png'
                    }, 
                    {
                        image: '/static/image/member/es4.png'
                    }, 
                    {
                        image: '/static/image/member/es5.png'
                    }
                ],
                currentIndex: 0,
                animationData: {},
                animationData2: {},
                currentSelect: 0,
                seqToView: '' // 滚动至序号
            }

        },
        methods: {
            tabClick(index) {
                if (index == this.currentSelect) {
                    return
                } else {
                    this.list[index].image = '/static/image/member/es' + index + '-selected.png'
                    this.list[this.currentSelect].image = '/static/image/member/es' + this.currentSelect + '-unselect.png'
                    this.currentSelect = index
                    this.currentIndex = index
                }

            },
            change(e) {
                this.currentIndex = e.detail.current
                console.log(this.currentIndex)
                this.tabClick(this.currentIndex)
                this.seqToView = 'seq-' + this.currentIndex // 滚动至选中序号位置
            },
            scroll: function(e) {
                console.log(e)
                this.old.scrollTop = e.detail.scrollTop
            },
        },
        onLoad() {
            // 收缩
            var animation = uni.createAnimation({
                duration: 400,
                timingFunction: 'ease',
            })
            animation.scale(1).step()
            this.animationData = animation.export()
            // 展开
            var animation2 = uni.createAnimation({
                duration: 400,
                timingFunction: 'ease',
            })
            animation2.scale(0.94).step()
            this.animationData2 = animation2.export()
        },
    }
</script>

<style>
    .scroll-top {
        margin: 34rpx 54rpx 0 0;
        white-space: nowrap;
        width: 100%;
    }

    .scroll-view-item {
        display: inline-block;
        padding: 0 20rpx;
        font-size: 32rpx;
        color: #666666;
        line-height: 74rpx;
        position: relative;
    }

    .scroll-view-item-view {
        display: flex;
        flex-direction: column;
        align-items: center;
        flex-wrap: wrap;
    }

    .scroll-top-item-image {
        width: 90rpx;
        height: 90rpx;
    }

    .scroll-top-item-text {
        margin-top: 24rpx;
        width: 143rpx;
        font-size: 24rpx;
        font-family: PingFangSC-Medium;
        font-weight: 400;
        color: #372E1D;
        display: block;
        line-height: normal;
        text-align: center;
    }
    
    .swiper-top {
        height: 100vh;
        margin-top: 88rpx;
    }

    .swiper-block {
        height: 300rpx;
        width: 100%;
    }

    .swiper-item {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: flex-start;
        overflow: unset;
    }

    .slide-image {
        height: 250rpx;
        width: 520rpx;
        border-radius: 9rpx;
        box-shadow: 0px 0px 30rpx rgba(0, 0, 0, 0.2);
        margin: 0rpx 30rpx;
        z-index: 1;
    }

    .active {
        transform: scale(1.14);
        transition: all 0.2s ease-in 0s;
        z-index: 20;
    }
</style>


添加新评论