UNPKG

nutui-uniapp

Version:

京东风格的轻量级移动端 Uniapp、Vue3 组件库(支持小程序开发)

118 lines (110 loc) 3.29 kB
import type { ComponentInternalInstance } from 'vue' import { onMounted, reactive, ref } from 'vue' import { useTouch } from '../_hooks' import { getRandomId } from '../_utils' type TouchPosition = 'left' | 'right' | 'top' | 'bottom' | '' export function useTabContentTouch(props: any, tabMethods: any, uni?: ComponentInternalInstance, useRect?: any) { const tabsContentRef = ref<HTMLElement>() const tabsContentID = `tabsContentRef-${getRandomId()}` const tabsContentRefRect = ref({ width: 0, height: 0 }) const initUniWidth = async () => { if (uni) { const rect = await useRect(tabsContentID, uni) tabsContentRefRect.value.width = rect.width || 0 tabsContentRefRect.value.height = rect.height || 0 } else { tabsContentRefRect.value.width = tabsContentRef.value?.clientWidth || 0 tabsContentRefRect.value.height = tabsContentRef.value?.clientHeight || 0 } } onMounted(() => { setTimeout(() => { initUniWidth() }, 100) }) const touchState = reactive({ offset: 0, moving: false, }) const touch = useTouch() let position: TouchPosition = '' const setoffset = (deltaX: number, deltaY: number) => { let offset = deltaX if (props.direction === 'horizontal') { position = deltaX > 0 ? 'right' : 'left' // 计算拖拽 百分比 offset = (Math.abs(offset) / tabsContentRefRect.value.width) * 100 } else { position = deltaY > 0 ? 'bottom' : 'top' offset = deltaY // 计算拖拽 百分比 offset = (Math.abs(offset) / tabsContentRefRect.value?.height) * 100 } // 拖拽阈值 85% if (offset > 85) offset = 85 switch (position) { case 'left': case 'top': // 起始tab拖拽拦截 if (tabMethods.isEnd()) { offset = 0 touchState.moving = false } break case 'right': case 'bottom': offset = -offset // 末位tab拖拽拦截 if (tabMethods.isBegin()) { offset = 0 touchState.moving = false } break } touchState.offset = offset } const touchMethods = { onTouchStart(event: Event) { if (!props.swipeable) return touch.start(event) }, onTouchMove(event: Event) { if (!props.swipeable) return touch.move(event) touchState.moving = true setoffset(touch.deltaX.value, touch.deltaY.value) if (props.direction === 'horizontal' && touch.isHorizontal()) { event.preventDefault() event.stopPropagation() } if (props.direction === 'vertical' && touch.isVertical()) { event.preventDefault() event.stopPropagation() } }, onTouchEnd() { if (touchState.moving) { touchState.moving = false switch (position) { case 'left': case 'top': // 大于 35%阈值 切换至下一 Tab if (touchState.offset > 35) tabMethods.next() break case 'right': case 'bottom': if (touchState.offset < -35) tabMethods.prev() break } } }, } return { touchMethods, touchState, tabsContentRef, tabsContentID } }