需求:Mat Tabs切换时用Mat Ink Bar/进度条跟踪进度
Mat Tab切换时的进度跟踪实现方案
方案一:使用Mat Progress Bar跟踪切换进度
通过监听标签页切换事件,结合进度条组件展示切换过程的进度,适合需要明确加载进度反馈的场景。
模板代码
<mat-progress-bar mode="determinate" [value]="progressValue" *ngIf="isTabChanging"></mat-progress-bar> <mat-tab-group (selectedTabChange)="onTabChange($event)"> <mat-tab label="标签页1">内容1</mat-tab> <mat-tab label="标签页2">内容2</mat-tab> <mat-tab label="标签页3">内容3</mat-tab> </mat-tab-group>
组件逻辑
import { Component } from '@angular/core'; import { MatTabChangeEvent } from '@angular/material/tabs'; @Component({ selector: 'app-tab-progress', templateUrl: './tab-progress.component.html', styleUrls: ['./tab-progress.component.css'] }) export class TabProgressComponent { progressValue = 0; isTabChanging = false; progressInterval: any; onTabChange(event: MatTabChangeEvent) { this.isTabChanging = true; this.progressValue = 0; // 模拟进度递增,实际项目中可替换为真实加载状态监听 this.progressInterval = setInterval(() => { this.progressValue += 10; if (this.progressValue >= 100) { clearInterval(this.progressInterval); this.isTabChanging = false; } }, 100); // 示例:如果标签页内容是异步加载,可在加载完成后直接完成进度 // this.loadTabContent(event.index).then(() => { // clearInterval(this.progressInterval); // this.progressValue = 100; // setTimeout(() => this.isTabChanging = false, 300); // }); } }
方案二:自定义Mat Ink Bar进度动画
修改原生Ink Bar的样式,添加过渡动画模拟进度移动效果,视觉上更贴合Material Design风格,无需额外组件。
模板代码
<mat-tab-group (selectedTabChange)="onTabChange($event)"> <mat-tab label="标签页A">内容A</mat-tab> <mat-tab label="标签页B">内容B</mat-tab> <mat-tab label="标签页C">内容C</mat-tab> </mat-tab-group>
自定义样式
/* 覆盖原生Ink Bar的过渡效果 */ .mat-mdc-tab-group .mdc-tab-indicator__content { transition: none; transform-origin: left center; } /* 进度动画类 */ .mat-mdc-tab-group .mdc-tab-indicator__content.progress-active { animation: inkBarProgress 0.8s forwards cubic-bezier(0.35, 0, 0.25, 1); } @keyframes inkBarProgress { 0% { width: 0; transform: translateX(0); } 50% { width: 100%; transform: translateX(0); } 100% { width: 100%; transform: translateX(calc(100% * var(--tab-index-diff))); } }
组件逻辑
import { Component, ViewChild } from '@angular/core'; import { MatTabGroup } from '@angular/material/tabs'; @Component({ selector: 'app-custom-ink-bar', templateUrl: './custom-ink-bar.component.html', styleUrls: ['./custom-ink-bar.component.css'] }) export class CustomInkBarComponent { @ViewChild(MatTabGroup) tabGroup!: MatTabGroup; previousTabIndex = 0; onTabChange(event: any) { const currentTabIndex = event.index; const tabIndexDiff = currentTabIndex - this.previousTabIndex; const inkBar = document.querySelector('.mdc-tab-indicator__content') as HTMLElement; if (inkBar) { inkBar.style.setProperty('--tab-index-diff', tabIndexDiff.toString()); inkBar.classList.add('progress-active'); // 动画结束后重置状态 setTimeout(() => { inkBar.classList.remove('progress-active'); this.previousTabIndex = currentTabIndex; }, 800); } } }
内容的提问来源于stack exchange,提问作者Ankit Mishra
相关产品推荐
相关产品推荐

