vue自定义轮播组件

该文章展示了一个使用Vue.js编写的滑动切换卡片组件,通过触屏的`touchstart`和`touchend`事件处理手动滑动,同时包含自动播放和停止的动画功能。组件利用数据绑定和过渡效果实现卡片的缩放、平移和透明度变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
    <view>
        <view class="swiperPanel">
            <view 
                class="swiperItem"
                v-for="(item, index) in swiperList"
                :key="index"
                @touchstart="startMove"
                @touchend="endMove($event, index)"
                :style="{ transform: itemStyle[index].transform, zIndex: itemStyle[index].zIndex, opacity: itemStyle[index].opacity }"
            >
                <view class="children">
                    <image class="pic" :src="(default + index + '.png')"></image>
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    let timer = null;
    export default {
        props: {
            swiperList: {
                type: Array,
                default: [0, 1, 2, 3]
            }
        },
        data() {
            return {
                slideNote: { x: 0, y: 0 },
                screenWidth: 0,
                itemStyle: [],
                defaultUrl: './static/cardPic/card_'
            }
        },
        created() {
            this.swiperList.forEach((item, index) => {
                this.itemStyle.push(this.getStyle(index))
            })
        },
        methods: {
            // 动画
            play() {
                if(timer) {
                    timer = null
                    clearInterval(timer)
                }
                timer = setInterval(() => {
                    this.slideAnimation()
                }, 300)
            },
            slideAnimation() {
                let newList = JSON.parse(JSON.stringify(this.itemStyle))
                let last = [newList.pop()];
                newList = last.concat(newList)
                this.itemStyle = newList
            },
            endPlay() {
                clearInterval(timer)
                timer = null
            },
            getStyle(e){
                if (e > this.swiperList.length / 2) {
                    var right = this.swiperList.lenght - e
                    return {
                        transform: 'scale(' + (1 - right / 10) + ') translate(-' + (right * 12) + '%,0px)',
                        zIndex: 9 - right,
                        opacity: 0.8 / right
                    }
                } else {
                    return {
                        transform: 'scale(' + (1 - e / 10) + ') translate(-' + (e * 12) + '%,0px)',
                        zIndex: 9 - e,
                        opacity: 0.8 / e
                    }
                }
            },
            startMove(e) {
                this.slideNode.x = e.changedTouches[0] ? e.changedTouches[0].pageX : 0
                this.slideNode.y = e.changedTouches[0] ? e.changedTouches[0].pageY : 0
            },
            endMove(e) {
                let newList = JSON.parse(JSON.stringify(this.itemStyle))
                if((e.changedTouchs[0].pageX - this.slideNote.x) < 0) {
                    // 向左滑动
                    var last = [newList.pop()]
                    newList = last.concat(newList)
                } else {
                    // 向右滑动
                    newList.push(newList[0])
                    newList.splice(0, 1)
                }
                this.itemStyle = newList
            }
        }
    }
</script>
<style lang="scss">
    .swiperPanel {
        margin: 340rpx 0 20rpx 0;
        height: 500rpx;
        width: 100%;
        overflow: hidden;
        position: relative;
        .swiperItem {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            transition: all .5s ease-in-out;
            .children {
                width: 330rpx;
                height: 485rpx;
                margin: 4rpx auto;
                .pic {
                    width: 100%;
                    height: 100%;
                    border-radius: 20px;    
                }
            }
        }
    }
</style>

父组件引用组件并传值:

import customSwiper from './swiperComponents'
components: { customSwiper }
<customSwiper ref="swiperRef" :swiper-list="cardsArr" />
手动播放:this.$refs['swiperRef'].play()
停止播放:this.$refs['swiperRef'].endPlay()

touchstart和touchend为手动滑动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木易66丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值