这是我对手机滑动手势的封装:
- 接受两个参数:
element:触发事件的目标元素
options:可接受六个函数,分别是触摸开始前后、触摸移动前后、触摸结束前后 - 返回一个对象:
swiping: Ref<boolean>表示是否正在移动
direction: ComputedRef<"left"|"right"|""|"down"|"up">表示移动的方向
distance: ComputedRef<{ x: number; y: number; } | null>表示移动的距离
import { computed, onMounted, onUnmounted, ref, Ref } from 'vue'
type Point = {
x: number
y: number
}
interface Options {
beforeStart?: (e: TouchEvent) => void
afterStart?: (e: TouchEvent) => void
beforeMove?: (e: TouchEvent) => void
afterMove?: (e: TouchEvent) => void
beforeEnd?: (e: TouchEvent) => void
afterEnd?: (e: TouchEvent) => void
}
export const useSwipe = (element: Ref<HTMLElement | undefined>, options?: Options) => {
const start = ref<Point>()
const end = ref<Point>()
const swiping = ref(false)
const distance = computed(() => {
if (!start.value || !end.value) {
return null
}
return {
x: end.value.x - start.value.x,
y: end.value.y - start.value.y
}
})
const direction = computed(() => {
if (!distance.value) {
return ''
}
const { x, y } = distance.value
if (Math.abs(x) > Math.abs(y)) {
return x > 0 ? 'right' : 'left'
} else {
return y > 0 ? 'down' : 'up'
}
})
const onStart = (e: TouchEvent) => {
options?.beforeStart?.(e)
swiping.value = true
end.value = start.value = {
x: e.touches[0].screenX,
y: e.touches[0].screenY
}
options?.afterStart?.(e)
}
const onMove = (e: TouchEvent) => {
options?.beforeMove?.(e)
if (!start.value) {
return
}
end.value = { x: e.touches[0].screenX, y: e.touches[0].screenY }
options?.afterMove?.(e)
}
const onEnd = (e: TouchEvent) => {
options?.beforeEnd?.(e)
swiping.value = false
options?.afterEnd?.(e)
}
onMounted(() => {
if (!element.value) {
return
}
element.value.addEventListener('touchstart', onStart)
element.value.addEventListener('touchmove', onMove)
element.value.addEventListener('touchend', onEnd)
})
onUnmounted(() => {
if (!element.value) {
return
}
element.value.removeEventListener('touchstart', onStart)
element.value.removeEventListener('touchmove', onMove)
element.value.removeEventListener('touchend', onEnd)
})
return { swiping, direction, distance }
}