You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 12如何实现支持百分比推进的带步骤进度条

Angular 12 平滑步进进度条实现(适配会员等级场景)

以下实现完全匹配需求:支持按实际百分比平滑推进、精确展示进度占比、标记等级节点、提示距下一等级剩余进度,和参考的React版本效果一致,无额外第三方依赖,可直接在Angular 12项目中使用。

1. 组件核心逻辑 stepper-progress.component.ts

import { Component, Input, OnInit, OnChanges } from '@angular/core';

export interface StepperStep {
  label: string; // 等级名称,例:普通会员、白银会员
  threshold: number; // 等级达成对应的进度百分比,取值0-100
}

@Component({
  selector: 'app-stepper-progress',
  templateUrl: './stepper-progress.component.html',
  styleUrls: ['./stepper-progress.component.scss']
})
export class StepperProgressComponent implements OnInit, OnChanges {
  @Input() steps: StepperStep[] = [];
  @Input() currentProgress = 0; // 传入实际进度值,范围0-100,支持小数
  @Input() progressColor = '#1677ff'; // 进度条高亮色
  @Input() trackColor = '#e5e7eb'; // 进度条轨道底色

  currentLevelIndex = 0;
  nextLevelRemain = 0;

  ngOnInit(): void {
    this.calculateStatus();
  }

  ngOnChanges(): void {
    this.calculateStatus();
  }

  private calculateStatus(): void {
    // 边界值处理
    if (this.currentProgress <= 0) {
      this.currentLevelIndex = 0;
      this.nextLevelRemain = this.steps[1]?.threshold || 100;
      return;
    }
    if (this.currentProgress >= 100) {
      this.currentLevelIndex = this.steps.length - 1;
      this.nextLevelRemain = 0;
      return;
    }
    // 计算当前所在等级、距下一等级剩余进度
    for (let i = 0; i < this.steps.length - 1; i++) {
      if (this.currentProgress >= this.steps[i].threshold && this.currentProgress < this.steps[i+1].threshold) {
        this.currentLevelIndex = i;
        this.nextLevelRemain = Number((this.steps[i+1].threshold - this.currentProgress).toFixed(1));
        break;
      }
    }
  }

  // 判断步骤节点是否已激活
  isStepActivated(index: number): boolean {
    return this.currentProgress >= this.steps[index].threshold;
  }
}

2. 组件模板 stepper-progress.component.html

<div class="stepper-container">
  <!-- 进度条轨道与填充层 -->
  <div class="progress-track" [style.background]="trackColor">
    <div 
      class="progress-fill"
      [style.width.%]="currentProgress"
      [style.background]="progressColor"
    ></div>

    <!-- 等级节点标记 -->
    <div 
      *ngFor="let step of steps; let i = index"
      class="step-node"
      [class.activated]="isStepActivated(i)"
      [style.left.%]="step.threshold"
      [style.borderColor]="isStepActivated(i) ? progressColor : trackColor"
      [style.background]="isStepActivated(i) ? progressColor : '#fff'"
    >
      <span class="step-label" [class.activated-label]="isStepActivated(i)">
        {{step.label}}
      </span>
    </div>
  </div>

  <!-- 进度提示文案 -->
  <div class="progress-tip" *ngIf="nextLevelRemain > 0">
    当前为<span class="level-name"> {{steps[currentLevelIndex].label}} </span>,距离下一等级还需 <span class="remain-value">{{nextLevelRemain}}%</span> 进度
  </div>
  <div class="progress-tip" *ngIf="nextLevelRemain === 0">
    已达到最高等级 <span class="level-name">{{steps[currentLevelIndex].label}}</span>
  </div>
</div>

3. 组件样式 stepper-progress.component.scss

.stepper-container {
  width: 100%;
  padding: 40px 20px 20px;
  box-sizing: border-box;
}

.progress-track {
  position: relative;
  width: 100%;
  height: 6px;
  border-radius: 3px;
}

.progress-fill {
  height: 100%;
  border-radius: 3px;
  // 核心:添加宽度过渡实现平滑推进效果
  transition: width 0.6s ease;
}

.step-node {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 3px solid;
  box-sizing: border-box;
  transition: all 0.3s ease;
  z-index: 2;

  .step-label {
    position: absolute;
    top: 24px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 14px;
    color: #666;
    white-space: nowrap;

    &.activated-label {
      color: #333;
      font-weight: 500;
    }
  }
}

.progress-tip {
  margin-top: 40px;
  text-align: center;
  font-size: 14px;
  color: #666;

  .level-name {
    color: #333;
    font-weight: 500;
    margin: 0 2px;
  }

  .remain-value {
    color: #1677ff;
    font-weight: 600;
    margin: 0 2px;
  }
}

4. 组件使用方式

在业务模块中声明该组件后,直接在页面中引入即可:

<app-stepper-progress
  [steps]="memberLevels"
  [currentProgress]="userCurrentProgress"
></app-stepper-progress>

业务组件中定义传入参数:

// 会员等级配置,阈值按从小到大排序,最后一级阈值设为100
memberLevels: StepperStep[] = [
  {label: '普通会员', threshold: 0},
  {label: '白银会员', threshold: 25},
  {label: '黄金会员', threshold: 50},
  {label: '铂金会员', threshold: 75},
  {label: '钻石会员', threshold: 100}
];
// 用户实际进度,支持任意0-100的数值,动态更新该值即可触发进度条平滑动画
userCurrentProgress = 32.7;

使用注意

  • 动态更新currentProgress值时,进度条会自动平滑滑动到对应位置,不会出现步骤间硬跳转的问题
  • 进度值支持传入小数,可精确展示0.1%级别的进度占比
  • 进度条颜色、节点大小、文案样式都可通过修改输入参数或样式文件自定义调整

内容的提问来源于stack exchange,提问作者Skymett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:21:30