为了实现左右滑动能够切换页面,便有了做成组件的想法。
代码实现
监听touchstart
,记录开始位置。
监听touchmove
,记录移动的位置,计算移动的方向,再把值设置给translateX
(计算结果的值要能够跟随手指移动),加入锁定方向,是为禁止斜方向滑动。
监听touchend
,在这里判断是否触发change事件。
<script setup>
import { ref } from "vue";
const props = defineProps({leftDisabled: {type: Boolean,default: false},rightDisabled: {type: Boolean,default: false}
});
const emit = defineEmits(["change"]);
// 纵向滑动时禁止水平滑动,水平滑动时禁止纵向滑动;
// 水平滑动结束超过屏幕二分之一时则toggle;
// 最大可滑动不超过屏幕的三分之二;
const startX = ref(0);
const startY = ref(0);
const endX = ref(0);
const endY = ref(0);
const dValueX = ref(0);
const dValueY = ref(0);
const translateX = ref(0);
const horizontalMoved = ref(false);
const verticalMoved = ref(false);
const onTouchStart = (e) => {startX.value = e.targetTouches[0].pageX;startY.value = e.targetTouches[0].pageY;
};
const onTouchMove = (e) => {endX.value = e.targetTouches[0].pageX;endY.value = e.targetTouches[0].pageY;dValueX.value = Math.abs(startX.value - endX.value);dValueY.value = Math.abs(startY.value - endY.value);const stopRange = window.screen.width - window.screen.width / 3;// 水平滑动长度大于纵向滑动长度,选择水平滑动if (dValueX.value > dValueY.value) {if (verticalMoved.value) {e.preventDefault();return;} else horizontalMoved.value = true;if (dValueX.value < stopRange) {if (startX.value > endX.value) {if (!props.leftDisabled) translateX.value = dValueX.value * -1; // 向左划} else {if (!props.rightDisabled) translateX.value = dValueX.value;}}e.preventDefault();} else {if (horizontalMoved.value) e.preventDefault();else verticalMoved.value = true;}
};
const onTouchEnd = (e) => {const range = window.screen.width / 2;if (horizontalMoved.value) {if (dValueX.value > range) {if (startX.value > endX.value) {// console.log("向左划");if (!props.leftDisabled) handleChange("left");} else if (startX.value < endX.value) {// console.log("向右划");if (!props.rightDisabled) handleChange("right");}}}horizontalMoved.value = false;verticalMoved.value = false;translateX.value = 0;startX.value = endX.value = 0;startY.value = endY.value = 0;
};
const handleChange = (value) => emit("change", value);
</script>
<template><div:style="`transition-duration: 200ms; transform: translateX(${translateX}px)`"><slot:touchstart="onTouchStart":touchmove="onTouchMove":touchend="onTouchEnd"></slot></div>
</template>
如何使用
在onToggleChange
里做路由跳转等其它操作。
<swipe-container @change="onToggleChange"><template #default="{ touchstart, touchmove, touchend }"><divclass="list"@touchstart="touchstart"@touchmove="touchmove"@touchend="touchend"><divv-for="item in list"class="card"></div></div></template>
</swipe-container>
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
![](https://img-blog.csdnimg.cn/2f6310dbbfbe4b3d993b15459187ccbc.jpeg#pic_center)
![](https://img-blog.csdnimg.cn/c2b3d9d4fefb4856b62d2110ac402dde.png#pic_center)
![](https://img-blog.csdnimg.cn/18e8c9ebb09f4147b3c7a13adff8ca56.png#pic_center)
![](https://img-blog.csdnimg.cn/40ff0a76780a47828e2483e748ee3d09.png#pic_center)
有需要的小伙伴,可以点击下方卡片领取,无偿分享