直接上代码:
<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>