移动端PFD预览组件Vue3(非插件)
需求:实现PDF预览效果(要手机触摸才有效果,PC滚动放大缩小看不到)
效果图:
代码:
<template><div class="go-JJFileReview03"><div class="pdf-box"><divclass="pdf-tab"@touchstart="handleTouchStart"@touchmove="handleTouchMove"@touchend="handleTouchEnd"><div class="img-container" v-for="item in imgUrlArr"><img:src="item.url":style="{ height: customHeight + 'px', width: customWidth + 'px' }"/></div></div></div></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue";const imgUrlArr = ref([{id: "1",url: "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",},{id: "2",url: "https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg",},{id: "3",url: "https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg",},{id: "4",url: "https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg",},{id: "5",url: "https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg",},{id: "6",url: "https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg",},{id: "7",url: "https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg",},
]);const customHeight = ref(350);
const customWidth = ref(340); // 添加 customWidth
// 触摸事件处理
let touchStartDistance = 0;
let touchMoveDistance = 0;
let touchStartX = 0;
let touchStartY = 0;
let touchMoveX = 0;
let touchMoveY = 0;// 处理触摸开始事件
const handleTouchStart = (event: TouchEvent) => {if (event.touches.length === 2) {touchStartDistance = getDistance(event.touches[0], event.touches[1]);} else if (event.touches.length === 1) {touchStartX = event.touches[0].clientX;touchStartY = event.touches[0].clientY;}
};
// 处理触摸移动事件
const handleTouchMove = (event: TouchEvent) => {if (event.touches.length === 2) {// 处理双指缩放touchMoveDistance = getDistance(event.touches[0], event.touches[1]);const delta = touchMoveDistance - touchStartDistance;const scaleFactor = 1 + delta / 1000; // 调整缩放敏感度// 应用缩放并限制范围customHeight.value *= scaleFactor;customWidth.value *= scaleFactor;touchStartDistance = touchMoveDistance;} else if (event.touches.length === 1) {// 处理单指滑动touchMoveX = event.touches[0].clientX;touchMoveY = event.touches[0].clientY;const deltaX = touchMoveX - touchStartX;const deltaY = touchMoveY - touchStartY;const pdfTab = document.querySelector(".pdf-tab") as HTMLElement;if (pdfTab) {pdfTab.scrollLeft -= deltaX;pdfTab.scrollTop -= deltaY;}touchStartX = touchMoveX;touchStartY = touchMoveY;}
};// 处理触摸结束事件
const handleTouchEnd = () => {// 重置触摸状态touchStartDistance = 0;touchMoveDistance = 0;touchStartX = 0;touchStartY = 0;touchMoveX = 0;touchMoveY = 0;
};const getDistance = (touch1: Touch, touch2: Touch) => {const dx = touch1.clientX - touch2.clientX;const dy = touch1.clientY - touch2.clientY;return Math.sqrt(dx * dx + dy * dy);
};onMounted(() => {window.addEventListener("resize", () => {// 处理窗口大小变化customHeight.value = window.innerHeight * 0.8;customWidth.value = window.innerWidth * 0.8; // 更新 customWidth});
});
// 组件卸载前移除事件监听器
onBeforeUnmount(() => {window.removeEventListener("resize", () => {customHeight.value = window.innerHeight * 0.8;customWidth.value = window.innerWidth * 0.8; // 更新 customWidth});
});
</script><style lang="scss" scoped>
.go-JJFileReview03 {width: 375px;height: 800px;.pdf-box {width: 100%;height: 100%;text-align: center;.pdf-tab {width: 100%;height: 100%;display: flex;flex-direction: column;overflow-x: auto;overflow-y: auto;touch-action: none; // 禁用默认的触摸行为}.img-container {flex: 0 0 auto; // 防止图片容器收缩margin: 0;padding: 0;}img {display: block; // 移除图片底部的间隙margin: 0;padding: 0;}}// 滚动条颜色::-webkit-scrollbar-thumb {background-color: #0674f1;}
}
</style>