vue自定义滑动轮播组件

文章详细描述了一个使用Vue.js编写的轮播组件,展示了如何处理touchstart、touchmove和touchend事件,以及如何根据用户触摸动作进行缩放、平移和切换滑动项。

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

直接上代码:

<view class="swiperPanel">
    <view
        class="swiperItem"
        v-for="(item, index) in swiperList"
        :key="index"
        @touchstart="startMove"
        @touchend="endMove($event, item)"
        :style="{ transform: itemStyle[index].transform, zIndex: itemStyle[index].zIndex, opacity: itemStyle[index].opacity }"
    >
        <view>{{ item.name }}</view>
    </view>
</view>
export default {
    props: {
        swiperList: {
            type: Array,
            default: []
        }
    },
    data() {
        return {
            itemStyle: [],
            touchTimer: null
        }
    },
    mounted() {
        this.swiperList.forEach((item, index)=> {
            this.itemStyle.push(this.getStyle(index))
        })
    },
    methods: {
        getStyle(e) {
            if(e > this.swiperList.length / 2) {
                var right = this.swiperList.length - e
                return {
                    transform: 'scale(' + (1 - right / 4) + ')translate(-' + (right * 72) + '%,0px',
                    zIndex: 8 - right,
                    opacity: 0.8 / right
                }
            } else {
                return {
                    transform: 'scale(' + (1 - e/ 4) + ')translate(-' + (e* 72) + '%,0px',
                    zIndex: 8 - e,
                    opacity: 0.8 / e
                }
            }
        },
        startMove(e) {
            this.slideNote.x = e.changedTouches[0] ? e.changedTouches[0].pageX : 0;
            this.slideNote.y = e.changedTouches[0] ? e.changedTouches[0].pageY : 0;
        },
        endMove(e, item) {
            let _this = this
            let deltaX = e.changedTouches[0].pageX = this.slideNote.x
            let deltaY = e.changedTouches[0].pageY = this.slideNote.y
            if(Math.abs(deltaY) > 50) {
                // 上下滑动不轮播
                e.preventDefault()
                return
            } else if(Math.abs(deltaY) < 20&& Math.abs(deltaX) < 30) {
                // 点击不轮播,降低滑动时轮播灵敏度
                e.preventDefault()
                return
            } else {
                var newList = JSON.parse(JSON.stringify(this.itemStyle))
                if((e.changedTouches[0].pageX - this.slideNote.x) < 0) {
                    // 向左滑动
                    var last = [newList.pop()]
                    newList = last.concat(newList)
                    // 滑动时定位当前dom
                    let obj = {}
                    this.swiperList.forEach((item1, index1)=> {
                        if(item1.activeName==item.activeName) {
                            if(index1==(_this.swiperList.length - 1)) {
                                obj = _this.swiperList[index1 + 1]
                            } else {
                                obj = _this.swiperList[index1 + 1]
                            }
                        }
                    })    
                } else {
                    newList.push(newList[0])
                    newList.splice(0, 1)
                    // 滑动时定位当前dom
                    let obj = {}
                    this.swiperList.forEach((item1, index1)=> {
                        if(item1.activeName==item.activeName) {
                            if(index1==0) {
                                obj = _this.swiperList[this.swiperList.length - 1]
                            } else {
                                obj = _this.swiperList[index1 - 1]
                            }
                        }
                    })
                }
                this.itemStyle = newList
            }
        }
    }
}

其他扩展:点击,长按,滑动共存,利用@touchstart,@touchmove,@touchend和setTimeout实现

<template>
    <div id="main">
        <button id="test-button" @touchstart="start" @touchmove="move" @touchend="end">
            touch测试
        </button>
    </div>
</template>

<script>
export default {
    name: "Vuetouch",
    data() {
        return {
            is_click: true,
            is_move: false,
        }
    },
    methods: {
        start() {
            this.is_click = true;   // 默认为点击事件
            clearTimeout(this.Loop); // 确保定时器已清除
            //若不采用箭头函数,需要修改执行环境,即this指向。
            //或在start函数开始时将this赋值给_this并在setTimeout回调函数中使用_this代替this
            this.Loop = setTimeout(() => { 
                this.is_click = false;
                // do something long press
            }, 800); // 当按击时间超出800ms时认为是长按事件
        },
        move() {
            clearTimeout(this.Loop); // 当发生滑动时清除定时器,阻止长按事件触发
            this.is_move = true;
        },
        end(event) {
            //当发生滑动时阻止touchend事件执行,直接返回
            if(this.is_move) {
                this.is_move = false;
                return;
            }
            let e = event || window.event;
            // 阻止浏览器默认事件,防止其产生干扰
            if(e.preventDefault){
                e.preventDefault();
            } else {
                e.returnValue = false;
            }
            clearTimeout(this.Loop); // 清除定时器
            // 没有触发长按事件和移动事件则为单击事件
            if(this.is_click) {
                // do something click
            }
        }
    },
}
</script>

<style scoped>
/* 禁止长按时选择文本 */
#test-button {
  -webkit-touch-callout:none;
  -webkit-user-select:none;
  -khtml-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  user-select:none;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木易66丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值