<template>
|
<view class="swipe-container">
|
<view
|
class="swipe-content"
|
:style="{ transform: `translateX(${translateX}px)` }"
|
@touchstart="handleTouchStart"
|
@touchmove="handleTouchMove"
|
@touchend="handleTouchEnd"
|
>
|
<wd-card>
|
<wd-cell-group :border="true">
|
<wd-cell title="单丝编号" :value="data.monofilamentNumber" />
|
<wd-cell title="理论长度" :value="data.amount + ' (m)'" />
|
<wd-cell title="生产长度" :value="data.actuallyLength + ' (m)'" />
|
<wd-cell title="重量" :value="data.actuallyWeight + ' (kg)'" />
|
</wd-cell-group>
|
</wd-card>
|
</view>
|
<view class="swipe-delete" @click="handleDelete">
|
<text class="delete-text">删除</text>
|
</view>
|
</view>
|
</template>
|
|
<script setup lang="ts">
|
import { ref } from "vue";
|
|
const props = defineProps({
|
data: {
|
type: Object,
|
default: () => {},
|
},
|
});
|
|
const emit = defineEmits(["delete", "swipe-open"]);
|
|
const translateX = ref(0);
|
const startX = ref(0);
|
const startY = ref(0);
|
const currentX = ref(0);
|
const isSwipeOpen = ref(false);
|
const deleteWidth = 80; // 删除按钮宽度
|
const isHorizontalSwipe = ref(false);
|
|
const handleTouchStart = (e: any) => {
|
startX.value = e.touches[0].clientX;
|
startY.value = e.touches[0].clientY;
|
currentX.value = translateX.value;
|
isHorizontalSwipe.value = false;
|
};
|
|
const handleTouchMove = (e: any) => {
|
const moveX = e.touches[0].clientX - startX.value;
|
const moveY = e.touches[0].clientY - startY.value;
|
|
// 判断是否为水平滑动(水平移动距离大于垂直移动距离)
|
if (!isHorizontalSwipe.value && Math.abs(moveX) > Math.abs(moveY) && Math.abs(moveX) > 10) {
|
isHorizontalSwipe.value = true;
|
}
|
|
// 只有水平滑动时才处理删除滑动
|
if (isHorizontalSwipe.value) {
|
e.stopPropagation();
|
const newTranslateX = currentX.value + moveX;
|
|
// 限制滑动范围:只能向左滑动,最大滑动距离为删除按钮宽度
|
if (newTranslateX <= 0 && newTranslateX >= -deleteWidth) {
|
translateX.value = newTranslateX;
|
} else if (newTranslateX < -deleteWidth) {
|
translateX.value = -deleteWidth;
|
} else if (newTranslateX > 0) {
|
translateX.value = 0;
|
}
|
}
|
};
|
|
const handleTouchEnd = (e: any) => {
|
// 只有水平滑动时才处理结束逻辑
|
if (isHorizontalSwipe.value) {
|
e.stopPropagation();
|
// 判断是否应该打开或关闭删除按钮
|
if (translateX.value < -deleteWidth / 2) {
|
// 滑动超过一半,打开删除按钮
|
translateX.value = -deleteWidth;
|
isSwipeOpen.value = true;
|
emit("swipe-open", props.data);
|
} else {
|
// 滑动不足一半,关闭删除按钮
|
translateX.value = 0;
|
isSwipeOpen.value = false;
|
}
|
}
|
isHorizontalSwipe.value = false;
|
};
|
|
const handleDelete = () => {
|
// 先关闭滑动
|
translateX.value = 0;
|
isSwipeOpen.value = false;
|
emit("delete", props.data);
|
};
|
|
// 关闭滑动的方法,供外部调用
|
const closeSwipe = () => {
|
if (isSwipeOpen.value) {
|
translateX.value = 0;
|
isSwipeOpen.value = false;
|
}
|
};
|
|
// 暴露方法供父组件调用
|
defineExpose({
|
closeSwipe,
|
isSwipeOpen,
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.swipe-container {
|
position: relative;
|
overflow: hidden;
|
margin-bottom: 8px;
|
}
|
|
.swipe-content {
|
position: relative;
|
transition: transform 0.3s ease;
|
z-index: 2;
|
background: #fff;
|
touch-action: pan-y;
|
}
|
|
.swipe-delete {
|
position: absolute;
|
right: 0;
|
top: 12px;
|
bottom: 12px;
|
width: 80px;
|
background: #ff4444;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
z-index: 1;
|
border-radius: 4px;
|
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
|
|
.delete-text {
|
color: #fff;
|
font-size: 14px;
|
font-weight: 500;
|
}
|
}
|
</style>
|