眼里容不得沙子 發表於 2026-4-2 11:52:00

前端实现进度条

<h1 data-id="heading-0">🧑‍💻 写在开头</h1>
<p>点赞 + 收藏 === 学会🤣🤣🤣</p>
<p>后端处理数据处理逻辑特别多的时候,并不会很及时返回数据,一般情况后端给前端返回进度,这个目前是前端自己返回进度到90,等到接口返回完成再到100%</p>
<h2 data-id="heading-0">1、设置全局样式</h2>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">    &lt;div class="loading-overlay" v-show="PageController.nextLoading"&gt;
      &lt;div class="loading-content"&gt;
      &lt;div style="text-align: center; padding: 20px"&gt;
          &lt;a-progress
            type="circle"
            :percent="PageController.progressPercent"
            :status="
            PageController.progressPercent === 100 ? 'success' : 'active'
            "
          /&gt;
          &lt;p style="margin-top: 10px"&gt;
            名单正在生成中,请您耐心等待。若您提前退出,该任务将在后台继续执行,您可稍后在任务列表中查看结果。
          &lt;/p&gt;
      &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
</pre>
</div>
<p>  </p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
z-index: 1000;
display: flex;
justify-content: center;
align-items: center;
}

.loading-content {
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
text-align: center;
}
</pre>
</div>
<p>  </p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">@observable nextLoading = false;
@observable progressPercent = 0;
@observable progressInterval = null;</pre>
</div>
<h2 data-id="heading-1">2、当触发的时候就调用进度条展示方法</h2>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">async onSubmit() {
    this.subLoading = true;
   
    //设置进度条状态开始
    this.PageController.setNextLoading(true);
   
    try {
      let data = this.PageController.uploadList.map((v) =&gt; {
      return {
          channelSize: v.channelSize ? v.channelSize : 0,
          id: v.id,
      };
      });
      
      // 启动进度条
      this.startProgressIncrement();
      let res = await this.PageController.submitChannelSize(data);
      this.$message.success('提交成功');
      // 接口调用成功后,确保进度条至少运行一段时间再完成
      this.completeProgress();
      //关闭进度条
      this.PageController.setNextLoading(false);
      
      this.subLoading = false;
      this.PageController.changeSubmitAfter(true);
      this.$router.replace({
      ...this.$Pages
          .Region_plan_jurisdiction_list_management_bpp_configuration_list,
      query: {
          id: this.$route.query.id,
          batchDate: this.$route.query.batchDate,
          salesType: 'bpp',
          status: 'details',
      },
      });
    } catch (error) {
    //如果接口报错就清空进度条
      if (this.PageController.progressInterval) {
      clearInterval(this.PageController.progressInterval);
      this.PageController.changeProgressInterval(null);
      }
      this.PageController.setNextLoading(false);
      
      this.subLoading = false;
    }
}
</pre>
</div>
<p>  </p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">startProgressIncrement() {
    // 重置进度
    this.PageController.changeProgressPercent(0);

    // 每100ms增加5%的进度,直到95%
    let progress = 0;
    const increment = 5;
    const intervalTime = 100;
    const maxProgress = 95;

    let interval = setInterval(() =&gt; {
      progress += increment;

      // 确保进度不超过最大值
      if (progress &gt;= maxProgress) {
      progress = maxProgress;
      }

      this.PageController.changeProgressPercent(progress);
      this.PageController.changeProgressInterval(interval);
    }, intervalTime);
}
// 完成进度条,确保有良好的用户体验
completeProgress() {
    // 清除现有的定时器
    if (this.PageController.progressInterval) {
      clearInterval(this.PageController.progressInterval);
      this.PageController.changeProgressInterval(null);
    }

    // 设置一个最小持续时间,确保用户能看到进度条的变化
    const minDuration = 1000; // 最小持续时间1秒
    const startTime = Date.now();

    // 立即将进度设置为95%
    this.PageController.changeProgressPercent(95);

    // 使用新的定时器完成最后的进度
    let interval = setInterval(() =&gt; {
      const elapsed = Date.now() - startTime;

      if (elapsed &gt;= minDuration) {
      // 时间到了,完成进度条
      this.PageController.changeProgressPercent(100);
      clearInterval(interval);
      this.PageController.setNextLoading(false);
      } else {
      // 根据已用时间计算进度
      const progress = 95 + (5 * elapsed) / minDuration;
      this.PageController.changeProgressPercent(Math.min(progress, 99));
      }
    }, 50);
}</pre>
</div>
<div>
<h3 id="tid-D8HBxE">如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。</h3>
</div>
<p><em><img src="https://img2024.cnblogs.com/blog/2149129/202501/2149129-20250122165814748-630765389.png" alt="" loading="lazy"></em></p><br><br>
来源:https://www.cnblogs.com/smileZAZ/p/19810764
頁: [1]
查看完整版本: 前端实现进度条