Quellcode durchsuchen

文件懒加载

wanghao vor 2 Monaten
Ursprung
Commit
93aebb12a5
1 geänderte Dateien mit 90 neuen und 11 gelöschten Zeilen
  1. 90 11
      src/views/pro-operation/drawing/index.vue

+ 90 - 11
src/views/pro-operation/drawing/index.vue

@@ -1,12 +1,18 @@
 <template>
   <el-scrollbar style="height: calc(100vh - 120px)">
     <div class="grid-container">
-      <div v-for="(box, index) in drawingData" :key="index" class="suit-box">
+      <div v-for="(box, index) in drawingData" :key="index" class="suit-box" :data-index="index">
         <div class="pdf-box">
           <PDFView
+            v-if="box.pdfPath && visiblePdfs[index]"
             :need-to-show-pdf="true"
             :pdf-source="baseUrl + box.pdfPath"
+            :key="'pdf-' + index + '-' + visiblePdfs[index]"
           />
+          <div v-else class="pdf-placeholder">
+            <!-- 可以添加一个简单的PDF图标或提示文字 -->
+            <el-icon :size="40"><Document /></el-icon>
+          </div>
         </div>
         <div class="suit-title">{{ box?.drawingTitle }}</div>
         <div class="suit-desc">{{ box?.created }}</div>
@@ -19,29 +25,91 @@
 import { drawingList } from "@/api/process/reportBreak";
 import { useProcessStore } from "@/store/modules/processView";
 import PDFView from "@/components/PDFView/index.vue";
+import { onMounted, ref, onBeforeUnmount } from "vue";
+import { Document } from '@element-plus/icons-vue';
 
 const processStore = useProcessStore();
 const drawingData = ref<any>([]);
+const visiblePdfs = ref<boolean[]>([]);
+const observer = ref<IntersectionObserver | null>(null);
+const lastVisibleIndex = ref<number>(-1);
 
 const baseUrl = import.meta.env.VITE_APP_UPLOAD_URL;
 
 onMounted(() => {
-  drawingList({ materialCode: processStore.scanInfo.materialCode }).then(
-    (res) => {
-      drawingData.value = res.data;
-    }
-  );
+  drawingList({ materialCode: processStore.scanInfo.materialCode }).then((res) => {
+    drawingData.value = res.data;
+    visiblePdfs.value = new Array(res.data.length).fill(false);
+    initIntersectionObserver();
+  });
+});
+
+onBeforeUnmount(() => {
+  cleanupObserver();
 });
+
+const initIntersectionObserver = () => {
+  cleanupObserver();
+  
+  observer.value = new IntersectionObserver((entries) => {
+    entries.forEach(entry => {
+      const index = parseInt(entry.target.getAttribute('data-index') || '0', 10);
+      
+      if (entry.isIntersecting) {
+        // 显示当前PDF
+        visiblePdfs.value[index] = true;
+        lastVisibleIndex.value = index;
+        
+        // 可以在这里添加预加载相邻PDF的逻辑
+        preloadAdjacentPdfs(index);
+      } else {
+        // 当元素离开视口时,根据策略决定是否卸载
+        if (shouldUnloadPdf(index, lastVisibleIndex.value)) {
+          visiblePdfs.value[index] = false;
+        }
+      }
+    });
+  }, {
+    rootMargin: '200px 0px', // 提前200px加载
+    threshold: 0.01
+  });
+
+  // 使用nextTick确保DOM已更新
+  setTimeout(() => {
+    document.querySelectorAll('.suit-box').forEach((box) => {
+      observer.value?.observe(box);
+    });
+  }, 0);
+};
+
+const preloadAdjacentPdfs = (currentIndex: number) => {
+  // 预加载前后各1个PDF
+  const preloadIndices = [currentIndex - 1, currentIndex + 1];
+  preloadIndices.forEach(i => {
+    if (i >= 0 && i < visiblePdfs.value.length && !visiblePdfs.value[i]) {
+      visiblePdfs.value[i] = true;
+    }
+  });
+};
+
+const shouldUnloadPdf = (index: number, lastVisibleIndex: number) => {
+  // 只保留当前可见项和相邻项的PDF加载
+  return Math.abs(index - lastVisibleIndex) > 2;
+};
+
+const cleanupObserver = () => {
+  if (observer.value) {
+    observer.value.disconnect();
+    observer.value = null;
+  }
+};
 </script>
 
 <style lang="scss" scoped>
 .grid-container {
   display: grid;
-  /*行间距*/
   grid-row-gap: 24px;
-  /*列间距*/
   grid-column-gap: 24px;
-
   overflow-y: auto;
   padding: 24px;
   width: calc(100% - 48px);
@@ -50,7 +118,7 @@ onMounted(() => {
   .suit-box {
     height: 343px;
     background-color: white;
-    border-radius: 16px 16px 16px 16px;
+    border-radius: 16px;
     display: flex;
     flex-direction: column;
     align-items: start;
@@ -60,6 +128,17 @@ onMounted(() => {
       height: 263px;
       width: 100%;
       overflow: hidden;
+      position: relative;
+    }
+
+    .pdf-placeholder {
+      height: 100%;
+      width: 100%;
+      background-color: #f5f5f5;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      color: #999;
     }
 
     .suit-title {
@@ -78,4 +157,4 @@ onMounted(() => {
     }
   }
 }
-</style>
+</style>