---
title: "StatCard 指标卡片"
description: "展示核心数字、趋势与进度的指标卡片"
category: Data
status: beta
since: 0.3.4
tags: [stat, metric, dashboard]
syncStatus: reviewed
verified: true
---

## 用法

### 默认样式
`iconClass` 的颜色类决定色调，缺省为主色，灰色不画色光；`meta` 在标签下方加一行说明。
::TuffDemoWrapper{demo="StatCardDefaultVariantDemo" code-lang="vue"}
---
code: |
  <template>
    <TxStatCard
      :value="2847"
      label="插件总数"
      meta="包含已启用与已停用插件"
      icon-class="i-carbon-download text-[var(--tx-color-primary)]"
      clickable
    />
    <TxStatCard
      :value="2516"
      label="已启用"
      icon-class="i-carbon-checkmark-outline text-[var(--tx-color-success)]"
    />
    <TxStatCard
      :value="18"
      label="待更新"
      icon-class="i-carbon-renew text-[var(--tx-color-warning)]"
    />
    <TxStatCard
      :value="331"
      label="已停用"
      icon-class="i-carbon-power text-[var(--tx-color-info)]"
    />
  </template>
---
::

### 趋势样式
`insight` 由 `from` 与 `to` 算出变化，渲染为带色胶囊；`insight.iconClass` 替换内置箭头。
::TuffDemoWrapper{demo="StatCardInsightVariantDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const activeUsers = ref(18200)
  const resourceLoad = ref(42)

  const activeInsight = { from: 16800, to: 18200, type: 'delta', color: 'success' }

  const resourceInsight = {
    from: 35,
    to: 42,
    type: 'percent',
    color: 'danger',
    iconClass: 'i-carbon-arrow-up-right',
    precision: 1,
  }
  </script>

  <template>
    <TxStatCard
      :value="activeUsers"
      label="活跃用户"
      icon-class="i-carbon-task text-[var(--tx-color-success)]"
      :insight="activeInsight"
    />
    <TxStatCard
      :value="resourceLoad"
      label="资源负载"
      icon-class="i-carbon-chip text-[var(--tx-color-warning)]"
      :insight="resourceInsight"
    >
      <template #value>
        <TxTextMorph :text="resourceLoad" /><span>%</span>
      </template>
    </TxStatCard>
  </template>
---
::

### 进度样式
`progress` 启用进度布局；进度环跟随 `iconClass` 的颜色。
::TuffDemoWrapper{demo="StatCardProgressVariantDemo" code-lang="vue"}
---
code: |
  <template>
    <TxStatCard
      variant="progress"
      :value="healthProgress"
      label="云同步"
      :meta="healthMeta"
      :progress="healthProgress"
      icon-class="i-carbon-cloud text-[var(--tx-color-primary)]"
    >
      <template #value>
        <TxTextMorph :text="healthProgress" /><span>%</span>
      </template>
    </TxStatCard>
  </template>
---
::

### 后台运营面板
与 `TxStatusBadge`、`TxProgressBar` 组合成后台首屏状态区。
::TuffDemoWrapper{demo="ComponentsOperationsStatusDemo" code-lang="vue"}
---
code: |
  <template>
    <TxStatCard
      variant="progress"
      value="99.9%"
      label="API 可用率"
      meta="正常"
      :progress="99"
      icon-class="i-carbon-cloud-monitoring text-[var(--tx-color-success)]"
    />
    <TxStatCard
      variant="progress"
      :value="18"
      label="待处理队列"
      meta="关注"
      :progress="64"
      icon-class="i-carbon-queued text-[var(--tx-color-warning)]"
    />
    <TxStatCard
      variant="progress"
      :value="2"
      label="告警"
      meta="阻塞"
      :progress="22"
      icon-class="i-carbon-warning-alt text-[var(--tx-color-danger)]"
    />
  </template>
---
::

### 最佳实践

- 计数类指标传 number，由默认格式化补分隔符；单位或动效布局复杂时用 `value` 插槽。
- 绝对变化用 `insight.type="delta"`，相对变化用 `insight.type="percent"`。
- `variant="progress"` 只用于有边界的指标（健康度、容量、配额、完成率），不用于无限增长的总量。
- `clickable` 只改变外观；跳转或操作由外层按钮、链接承载。
- 由父级给卡片宽度（grid 单元格、被拉伸的 flex 项）；`inline-block` 等按内容收缩的父级会让它塌陷。

## API 参考

### 属性

| 属性名 | 类型 | 默认值 | 说明 |
|------|------|---------|------|
| `value` | `number \| string` | - | 主数值；number 按默认格式化补分隔符。 |
| `label` | `string` | - | 指标标签；趋势与进度布局中显示在顶部。 |
| `iconClass` | `string` | `''` | 装饰图标 class，尺寸由组件决定；颜色类为图标、色光与进度环着色。 |
| `clickable` | `boolean` | `false` | 只加指针光标，不绑定点击行为。 |
| `insight` | `StatCardInsight` | - | 变化指标；启用后标签上移并渲染趋势胶囊。 |
| `variant` | `StatCardVariant` | `'default'` | 布局变体（`default` \| `progress`）。 |
| `progress` | `number` | - | 进度百分比；传入即启用进度布局，裁剪到 0–100。 |
| `meta` | `string` | - | 说明行；`meta` 插槽优先。 |
| `ariaLabel` | `string` | - | `role="group"` 的可访问名称；缺省时由可见标签命名。 |

### 插槽

| 插槽 | 说明 |
|------|------|
| `value` | 自定义数值区域。 |
| `label` | 自定义标签区域。 |
| `meta` | 说明行；与 `meta` 都省略时不占行。 |

### StatCardInsight

| 字段 | 类型 | 默认值 | 说明 |
|------|------|---------|------|
| `from` | `number` | - | 基准值。 |
| `to` | `number` | - | 当前值。 |
| `type` | `'percent' \| 'delta'` | `'percent'` | 百分比变化或绝对增量。 |
| `color` | `'success' \| 'danger' \| 'warning' \| 'info' \| string` | - | 涨幅色，也决定胶囊底色；缺省时 ≥0 为 success、<0 为 danger。 |
| `iconClass` | `string` | - | 自定义趋势图标 class；缺省为内置 SVG 箭头。 |
| `suffix` | `string` | - | 后缀，`percent` 默认为 `%`；与数值紧贴，需要空格时写进后缀，如 `' pts'`。 |
| `precision` | `number` | - | 小数位数；缺省时 `delta` 为 0、`percent` 为 1。 |

### CSS 变量

| 变量 | 来源 | 说明 |
|------|------|------|
| `--tx-stat-card-slot` | 组件默认 `72px`，可在组件的 `style` 上覆写 | 右侧方形槽位的边长，图标与进度环按它绘制；窄卡时为 `36px`。 |
| `--tx-stat-card-slot-inset` | 组件默认 `18px`，可在组件的 `style` 上覆写 | 槽位到卡片右边缘的距离；窄卡布局不读取。 |
| `--tx-stat-card-icon-color` | 组件写入（图标计算色） | 色光、图标墨色与进度环的来源色；由组件独占，不要用 `:style` 绑定。 |

## 概述

- 根节点为 `role="group"`，由可见标签经 `aria-labelledby` 命名；Dashboard 中给出相邻标题，避免只显示裸数字。
- 挂载、`iconClass` / `variant` 变化及页面主题切换后读取图标计算色：有色相时加 `tx-stat-card--tinted` 并画色光；灰色图标（含 `--tx-color-info`）不画色光。
- 卡片内容区窄于 240px 时（容器查询，非视口），槽位缩成 36px 并移到右上角。
- 涨幅胶囊把符号、数值与单位渲染为一体（`+16.7%`）；数值使用等宽数字，刷新时不抖动。
- hover 只把描边换成 `--tx-border-color`，没有动效。
- 减少动态效果时色斑停止漂移、色光直接出现，进度弧直接跳到新值。

## 技术实现

- 色光是三团模糊色斑，只动画 `transform`，由合成器移动，不逐帧重新模糊。
- 源码：`packages/tuffex/packages/components/src/stat-card/`。

<TuffDocSourceLink />
