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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:09:28