Vue3實(shí)現(xiàn)一個(gè)可左右滑動操作組件的示例代碼
為了實(shí)現(xiàn)左右滑動能夠切換頁面,便有了做成組件的想法。

代碼實(shí)現(xiàn)
監(jiān)聽touchstart,記錄開始位置。
監(jiān)聽touchmove,記錄移動的位置,計(jì)算移動的方向,再把值設(shè)置給translateX(計(jì)算結(jié)果的值要能夠跟隨手指移動),加入鎖定方向,是為禁止斜方向滑動。
監(jiān)聽touchend,在這里判斷是否觸發(fā)change事件。
<script setup>
import { ref } from "vue";
const props = defineProps({
leftDisabled: {
type: Boolean,
default: false
},
rightDisabled: {
type: Boolean,
default: false
}
});
const emit = defineEmits(["change"]);
// 縱向滑動時(shí)禁止水平滑動,水平滑動時(shí)禁止縱向滑動;
// 水平滑動結(jié)束超過屏幕二分之一時(shí)則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>如何使用
<swipe-container @change="onToggleChange">
<template #default="{ touchstart, touchmove, touchend }">
<div
class="list"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
>
<div
v-for="item in list"
class="card"
></div>
</div>
</template>
</swipe-container>到此這篇關(guān)于Vue3實(shí)現(xiàn)一個(gè)可左右滑動操作組件的示例代碼的文章就介紹到這了,更多相關(guān)Vue左右滑動操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue 設(shè)置proxyTable參數(shù)進(jìn)行代理跨域
這篇文章主要介紹了vue 設(shè)置proxyTable參數(shù)進(jìn)行代理跨域的相關(guān)資料,及代理跨域的概念原理,需要的朋友可以參考下2018-04-04
vue+echarts繪制省份地圖并添加自定義標(biāo)注方式
這篇文章主要介紹了vue+echarts繪制省份地圖并添加自定義標(biāo)注方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Vue.js學(xué)習(xí)記錄之在元素與template中使用v-if指令實(shí)例
這篇文章主要給大家介紹了關(guān)于Vue.js學(xué)習(xí)記錄之在元素與template中使用v-if指令的相關(guān)資料,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),相信對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-06-06
vue element el-form 多級嵌套驗(yàn)證的實(shí)現(xiàn)示例
本文主要介紹了vue element el-form 多級嵌套驗(yàn)證的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
詳解如何在Vue項(xiàng)目中實(shí)現(xiàn)累加動畫
這篇文章主要為大家詳細(xì)介紹了如何在你的Vue項(xiàng)目中實(shí)現(xiàn)累加動畫,文中的示例代碼簡潔易懂,具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2023-06-06
使用 vue 實(shí)例更好的監(jiān)聽事件及vue實(shí)例的方法
這篇文章主要介紹了使用 vue 實(shí)例更好的監(jiān)聽事件及vue實(shí)例的方法,介紹了一種新增 vue 實(shí)例的方法,單獨(dú)監(jiān)聽事件,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
vue父組件觸發(fā)事件改變子組件的值的方法實(shí)例詳解
這篇文章主要介紹了vue父組件觸發(fā)事件改變子組件的值的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05

