如何在SCSS中调用TS变量值?纯CSS饼图百分比动态控制
这个问题其实戳中了预编译CSS(比如SCSS)和运行时JS/TS的核心差异——SCSS变量是编译阶段就确定的,编译完成后会被替换成具体值,根本没法在运行时通过TS直接修改。所以我们得换个思路,用CSS自定义属性(也就是常说的CSS变量)作为中间层,实现动态控制饼图百分比的需求。
下面是具体的实现步骤,结合你的代码来改造:
1. 改造SCSS代码,用CSS变量替代静态百分比
首先,我们把SCSS里的静态percentage:32换成CSS变量,同时保留默认值以防万一。这样SCSS编译后,CSS会保留这个变量的引用,运行时可以动态修改:
// 先给CSS变量设置默认值(和原来的32一致),也可以直接在饼图容器上定义 :root { --chart-one-percentage: 32; } $configs: ( chart-one: ( svgSize: 200px, // 用CSS变量替代静态数值,var()第二个参数是默认值 percentage: var(--chart-one-percentage, 32), strokeWidth: 1px, backgroundColor: #305556, foregroundColor: #79be9b, labelColor: #c6e8d7, labelFontSize: 2.5rem, duration: 3s, animationDelay: 1s ) ); // 假设你的饼图是基于SVG环形实现的,这里补充关键的计算逻辑(根据你的实际饼图代码调整) .chart-one { $chart: map-get($configs, chart-one); width: map-get($chart, svgSize); height: map-get($chart, svgSize); .progress-ring__circle { stroke-width: map-get($chart, strokeWidth); stroke: map-get($chart, backgroundColor); // 环形的周长(假设半径是SVG尺寸的一半减去 strokeWidth 的一半,简化计算用100作为基准) $circumference: 2 * 3.14 * 100; &.progress-ring__circle--foreground { stroke: map-get($chart, foregroundColor); // 用CSS变量计算 stroke-dasharray,实现百分比对应的环形长度 stroke-dasharray: calc(var(--chart-one-percentage) / 100 * #{$circumference}) #{$circumference}; transition: stroke-dasharray map-get($chart, duration) ease map-get($chart, animationDelay); } } .chart-label { color: map-get($chart, labelColor); font-size: map-get($chart, labelFontSize); } }
2. 在TS代码中动态设置CSS变量
接下来,在TS里计算出this.performance后,把它赋值给对应的CSS变量。这里以Angular为例(如果是其他框架,思路完全一致,只是获取DOM元素的方式不同):
// 假设是Angular组件,先引入ViewChild获取饼图容器 import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-performance-chart', templateUrl: './performance-chart.component.html', styleUrls: ['./performance-chart.component.scss'] }) export class PerformanceChartComponent implements OnInit { total: number; completed: number; performance: number; // 通过模板引用获取饼图容器元素 @ViewChild('chartContainer') chartContainer: ElementRef; ngOnInit(): void { // 替换成你的实际数据获取逻辑 const data = [ [{ TOTAL: 100 }], [], [{ COMPLETED: 32 }] ]; this.total = data[0][0].TOTAL; this.completed = data[2][0].COMPLETED; // 计算百分比,可选:用Math.round取整让显示更整齐 this.performance = Math.round((this.completed / this.total) * 100); // 动态设置CSS变量 this.chartContainer.nativeElement.style.setProperty( '--chart-one-percentage', this.performance.toString() ); // 更简便的方式:直接在模板里绑定 // 比如在模板的容器元素上写: // <div #chartContainer [style.--chart-one-percentage]="performance" class="chart-one">...</div> // 这样就不需要用ViewChild手动设置了 } }
原理说明
SCSS编译时会把var(--chart-one-percentage)保留为原生CSS变量,而不是替换成固定值。当TS在运行时修改这个变量的值时,浏览器会自动重新计算相关的CSS属性(比如stroke-dasharray),从而动态更新饼图的显示百分比。
如果你的饼图不是用SVG环形实现的,而是用其他方式(比如clip-path、transform旋转),只需要把CSS变量用到对应的计算逻辑里就行——核心都是用CSS变量作为编译时SCSS和运行时TS的桥梁。
内容的提问来源于stack exchange,提问作者Kirandeep Kaur
相关产品推荐
相关产品推荐

