一、前言
简述
- 通过
触摸事件判定开始结束的偏移方向和值,以此达到监听上下左右滑动事件的目的
- 核心事件:
touchstart(开始触摸)、touchend(结束触摸)
应用场景 ↓
- 切换tab
- 切换页面
- 切换步骤
- 加载新数据
- 刷新页面
- 弹窗
- 提示
- ......
二、实用案例及代码注释解析
touchstart:手指触摸屏幕时触发,即使已经有手指在屏幕上也会触发。
touchend:手指从屏幕时移开时触发。
案例一、tab或步骤切换
<template>
<view style="height:100vh;">
<view class="tab-box">
<view :class="['tab-item',{'active':tabFlag===item}]"
v-for="item in 5" :key="item"
@click="tabFlag=item">{{ item }}
</view>
</view>
<view style="background-color: aqua;height: 800rpx" @touchstart="touchStart" @touchend="touchEnd">
内容{{ tabFlag }}
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
const tabFlag = ref(1);
const touchStartX = ref(null);
const touchStartY = ref(null);
function touchStart(e) {
touchStartX.value = e.touches[0].clientX;
touchStartY.value = e.touches[0].clientY;
console.log("开始触摸", e);
}
function touchEnd(e) {
let deltaX = e.changedTouches[0].clientX - touchStartX.value;
let deltaY = e.changedTouches[0].clientY - touchStartY.value;
if(Math.abs(deltaX) > 50 && Math.abs(deltaX) > Math.abs(deltaY)) {
if(deltaX < 0 && tabFlag.value < 5) {
tabFlag.value++;
}
if(deltaX >= 0 && tabFlag.value > 1) {
tabFlag.value--;
}
}
}
</script>
<style lang="scss" scoped>
.active {
background-color: pink;
color: #ffffff;
}
.tab-box {
display: flex;
margin-bottom: 20rpx;
.tab-item {
flex: 1;
text-align: center;
line-height: 80rpx;
}
}
</style>
案例二、切换页面及可交互场景
<template>
<view
style="height:80vh;background-color: aqua;"
@touchstart="touchStart"
@touchend="touchEnd"
>
内容
</view>
</template>
<script setup>
import { ref } from 'vue';
const touchStartX = ref(null);
const touchStartY = ref(null);
function touchStart(e) {
touchStartX.value = e.touches[0].clientX;
touchStartY.value = e.touches[0].clientY;
}
function touchEnd(e) {
console.log("触摸结束", e);
let deltaX = e.changedTouches[0].clientX - touchStartX.value;
let deltaY = e.changedTouches[0].clientY - touchStartY.value;
if(Math.abs(deltaX) > 50 && Math.abs(deltaX) > Math.abs(deltaY)) {
if(deltaX >= 0) {
uni.switchTab({
url: '/pages/index'
});
}
else {
uni.showActionSheet({
itemList: ['v', '我', '5', '0'],
success(res) {
console.log(res.tapIndex);
},
fail(res) {
console.log(res.errMsg);
}
});
}
}
else if(Math.abs(deltaY) > 50 && Math.abs(deltaX) < Math.abs(deltaY)) {
if(deltaY < 0) {
uni.showModal({
title: '系统提示',
content: '触发上滑',
success: function(res) {
if(res.confirm) {
console.log('点击了确认');
}
else {
console.log('点击了取消');
}
}
});
}
else {
uni.showLoading({
title: '加载中...',
icon: 'none'
});
setTimeout(() => {
uni.hideLoading();
}, 913);
}
}
}
</script>