2026-week-4st

10 阅读2分钟

循环引用的问题

问题的根源是一个典型的循环依赖问题。让我分析一下:1. user.js 导入了 loginPassword 从 @/api 2. api/index.js 导入了 createRequest 从 @/utils/request/index 3. utils/request/index.js 导入了 useUserStore 从 @/store/modules/user 这形成了循环依赖:user.js → api/index.js → utils/request/index.js → user.js 当页面刷新或热更新时,模块加载顺序被打乱,导致 createRequest 在 api/index.js 中使用时还未初始化。

这个问题会导致页面部分组件切换的时候会报错。导致显示异常!!! 需要格外注意规避!!!

背景虚化

image.png

  .popup-content {
    position: relative;
    height: 100%;
    width: 100%;
    border-radius: 8px;
    overflow: hidden;
  }
  
  /* 背景虚化层 */
  .backdrop-blur {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(255, 255, 255, 0.8);
    -webkit-backdrop-filter: blur(29px);
    backdrop-filter: blur(29px);
    // 这个样式
    z-index: 1;
  }

清空query 参数

await router.replace({  注意是异步的!!!!!!!!!!!
    query: {},
});

H5 列表列表组件分页以及下拉加载更多

 <van-pull-refresh v-model="isLoading" head-height="100" loading-text="刷新中" success-text="刷新成功" @refresh="onRefresh">
       <van-list v-model:loading="loadMore" :immediate-check="false" :finished="finished" finished-text="没有更多了" @load="onLoad">
         <div ref="caseListWrapper">
           <!-- 将数据按页码分组,为每个页码添加容器 -->
           <van-back-top :immediate="true" @click="backtoTop" />
           <div
             v-for="pageNum in Math.ceil(tableData.length / page.pageSize)"
             :key="pageNum"
             :ref="(el) => setPageContainerRef(el, pageNum)"
             class="page-container"
             :data-page="pageNum"
           >
             <CaseList :data="tableData.slice((pageNum - 1) * page.pageSize, pageNum * page.pageSize)" />
           </div>
         </div>
       </van-list>
     </van-pull-refresh>
     
script

// 页码容器引用管理
 const pageContainers = ref({});
 
   // 设置页码容器引用
 const setPageContainerRef = (el, pageNum) => {
   if (el) {
     pageContainers.value[pageNum] = el;
   } else {
     delete pageContainers.value[pageNum];
   }
 };
 
 // 初始化Intersection Observer
 const initObserver = () => {
   if (observer) {
     observer.disconnect();
   }

   const scrollContainer = document.querySelector('.main-page');
   if (scrollContainer) {
     scrollContainer.addEventListener('scroll', scrollHandle);
   }

   observer = new IntersectionObserver(
     (entries) => {
       // 按位置排序,找到最顶部的可见页码容器
       const visibleEntries = entries.filter((entry) => entry.isIntersecting);
       if (visibleEntries.length === 0) return;

       visibleEntries.sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
       const firstVisibleEntry = visibleEntries[0];
       // 获取页码
       const pageNum = parseInt(firstVisibleEntry.target.dataset.page);

       if (!isNaN(pageNum)) {
         // 确保页码在有效范围内
         const validPage = Math.max(1, Math.min(pageNum, Math.ceil(page.total / page.pageSize) || 1));
         currentVisiblePage.value = validPage;
         // 更新页码并通知父组件
         page.page = validPage;
         // 更新页码并通知父组件
         const tempPage = { ...page };
         emit('updateNav', 'showNav', true, tempPage, 'initObserver');
       }
     },
     {
       root: null, // 使用视口作为根元素
       rootMargin: '0px',
       threshold: 0.1, // 元素10%可见时触发
     },
   );
 };
 
 
 // 观察所有页码容器
 const observePageContainers = () => {
   if (!observer) return;

   // 停止观察所有现有元素
   observer.disconnect();

   // 观察所有页码容器
   Object.values(pageContainers.value).forEach((container) => {
     observer.observe(container);
   });
 };

文件分片上传,单个分片生成md5

 const uploadSingleChunk = async (chunkIndex) => {
   const start = chunkIndex * CHUNK_SIZE;
   const end = Math.min(start + CHUNK_SIZE, file.value.size);
   const chunkBlob = file.value.slice(start, end);
   const spark = new SparkMD5.ArrayBuffer();
   const arrayBuffer = await chunkBlob.arrayBuffer();
   spark.append(arrayBuffer);
   const chunkMd5 = spark.end();
   // 构建FormData
   const formData = new FormData();
   formData.append('task_id', task_id.value);
   formData.append('chunk_md5', chunkMd5);
   // console.log('chunk_md5', chunkMd5, chunkBlob);
   formData.append('chunk_id', chunkIndex);
   formData.append('chunk', chunkBlob);

   abortController.value = new AbortController();
   try {
     const res = await request.post('/h5/upload/multi/upload-chunk', formData, {
       signal: abortController.value.signal,
       onUploadProgress: (e) => {
         // 计算当前分片的临时进度,叠加到整体进度
         const chunkProgress = e.loaded / e.total;
         const totalUploaded = uploadedChunks.value.length + chunkProgress;
         progress.value = Math.round((totalUploaded / totalChunks.value) * 100);
       },
     });
     upload_finish.value = get(res, 'data.finished', 0);
     upload_finish.value ? (finish_res.value = res) : null;
     // 分片上传成功,记录已传分片
     uploadedChunks.value.push(chunkIndex);
   } catch (err) {
     if (err.name !== 'CanceledError') {
       console.error(`分片${chunkIndex}上传失败,重试中...`, err);
       retryCount.value++;
       if (retryCount.value < RETRY_COUNT) {
         await new Promise((resolve) => setTimeout(resolve, 1000)); // 1秒后重试
         await uploadSingleChunk(chunkIndex); // 重试
       } else {
         console.error(`分片${chunkIndex}上传失败,重试${RETRY_COUNT}次后仍失败`);
         retryCount.value = 0; // 重置重试次数
       }
     }
   }
 };

数字添加千分位标点

 parseInt(num,10).toLocaleString();

z-index 使用的时候,不要一上来就设置很大的数字 从1 慢慢递增即可