Appearance
BizStatistic 指标组件(统计卡)
指标展示唯一组件,已并入原 BizTrend(趋势指标)全部能力,形成三种能力维度:
- 卡片形态(默认):标题 + 图标 + 数值(精度/千分位/前后缀/滚动动画)+ 趋势涨跌 + loading 骨架 + 尺寸档位——看板 KPI 行标准件;
- inline 内联形态(
inline,原 BizTrend):数值 + 涨跌箭头 + 变化率 + 可选迷你走势一行展示——表格列 / 卡片内嵌 / 同比环比组合; - sparkline 迷你走势(
trend-data):纯手绘 SVG 零图表库依赖,卡片与内联形态均可开启,颜色随涨跌口径。
涨跌口径一套体系(同轴翻转,不出现两套口径打架):cn 红涨绿跌(默认)与 good 涨绿跌红(涨=好)互为翻转,reverse 即翻转当前口径——cn + reverse 得涨绿跌红(原 BizTrend 行为);good + reverse 得降绿升红(成本/故障率等「降了才好」的指标在 good 系看板中的标准配法)。与 BizAmount 互补:Amount 管单值格式化,Statistic 管指标结构;多卡横排翻页用 BizStatisticGroup(items 全量透传本组件 props)。
原 BizTrend 已删除。迁移对照:
value / rate / digits / arrow / reverse / size原名保留;direction → trend;data → trend-data;使用时补inline。
基础用法
今日销售额
¥2,618,400
+12.4%较昨日
在线设备
1,024台
-8较昨日
库存周转天数
6.5天
持平较上周
value 为 number 时走精度 + 千分位;trend + trend-text 渲染涨跌(默认 cn 口径红涨绿跌);icon 右上角图标。<script setup lang="ts">
/** 场景:卡片基础——KPI 三卡(数值精度/千分位格式化 + 趋势涨跌 + 右上角图标) */
import { Goods, Monitor, TrendCharts } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
</script>
<template>
<div style="display: grid; grid-template-columns: repeat(3, minmax(200px, 1fr)); gap: 12px; max-width: 760px">
<BizStatistic title="今日销售额" :value="2618400" prefix="¥" :trend="'up'" trend-text="+12.4%" trend-label="较昨日" :icon="TrendCharts" />
<BizStatistic title="在线设备" :value="1024" suffix="台" :trend="'down'" trend-text="-8" trend-label="较昨日" :icon="Monitor" />
<BizStatistic title="库存周转天数" :value="6.5" :precision="1" suffix="天" :trend="'flat'" trend-text="持平" trend-label="较上周" :icon="Goods" />
</div>
</template>
显示代码
loading 骨架
本月销售额
骨架开关
loading 时数值区替换为骨架屏;接口返回后关闭骨架展示数值与趋势。<script setup lang="ts">
/** 场景:loading 骨架——数值区骨架屏,加载完成后展示数值与趋势(模拟接口请求) */
import { ref } from 'vue'
import { ElButton, ElSwitch } from 'element-plus'
import { BizStatistic } from 'vue3-ep-biz-lib'
const loading = ref(true)
const count = ref(0)
const reload = (): void => {
loading.value = true
setTimeout(() => {
count.value += 1
loading.value = false
}, 1500)
}
setTimeout(() => {
loading.value = false
}, 1500)
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 360px">
<BizStatistic
title="本月销售额"
:value="loading ? undefined : 1284560"
prefix="¥"
:loading="loading"
:trend="loading ? undefined : 'up'"
:trend-text="loading ? undefined : '+9.6%'"
trend-label="环比"
/>
<div style="display: flex; align-items: center; gap: 12px; font-size: 13px">
<ElSwitch v-model="loading" /> 骨架开关
<ElButton size="small" type="primary" plain :disabled="loading" @click="reload">重新加载({{ count }})</ElButton>
</div>
</div>
</template>
显示代码
趋势涨跌与口径切换
本周销售额
¥186,420
+8.2%较上周
本周新客数
1,284人
-3.1%较上周
接口成功率
99.97%
+0.02%
平均响应时长
128ms
-16ms
客诉率
0.62%
-18.4%
错误数(近1h)
3
+3
cn 红涨绿跌(默认);good 涨绿跌红(涨=好);reverse 与 trend-mode 同轴翻转(XOR)——客诉率(good+reverse)下降 18.4% 渲染为绿色利好色
上排
cn 口径(红涨绿跌);下排 good 口径(涨=绿=好)与 good + reverse(降=绿)三种口径对照。<script setup lang="ts">
/** 场景:趋势涨跌与口径切换——同一组指标分别用 cn(红涨绿跌)/ good(涨绿跌红)/ reverse(等效 good)三种口径演示 */
import { CircleCheckFilled, WarningFilled } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
interface ModeCard {
title: string
value: number | string
prefix?: string
suffix?: string
trend: 'up' | 'down' | 'flat'
text: string
}
/** cn 口径(默认):常规经营指标红涨绿跌,符合国内配色习惯 */
const cnCards: ModeCard[] = [
{ title: '本周销售额', value: 186420, prefix: '¥', trend: 'up', text: '+8.2%' },
{ title: '本周新客数', value: 1284, suffix: '人', trend: 'down', text: '-3.1%' },
]
/** good / reverse 口径:监控类「涨了才好」与成本类「降了才好」的指标 */
const goodCards: Array<ModeCard & { mode: 'cn' | 'good'; reverse: boolean }> = [
{ title: '接口成功率', value: '99.97%', trend: 'up', text: '+0.02%', mode: 'good', reverse: false },
{ title: '平均响应时长', value: '128ms', trend: 'down', text: '-16ms', mode: 'good', reverse: false },
{ title: '客诉率', value: '0.62%', trend: 'down', text: '-18.4%', mode: 'good', reverse: true },
{ title: '错误数(近1h)', value: 3, trend: 'up', text: '+3', mode: 'cn', reverse: false },
]
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 14px; max-width: 820px">
<div style="display: grid; grid-template-columns: repeat(2, minmax(200px, 1fr)); gap: 12px">
<BizStatistic
v-for="card in cnCards"
:key="card.title"
:title="card.title"
:value="card.value"
:prefix="card.prefix ?? ''"
:suffix="card.suffix ?? ''"
:trend="card.trend"
:trend-text="card.text"
trend-label="较上周"
trend-mode="cn"
/>
</div>
<div style="display: grid; grid-template-columns: repeat(2, minmax(200px, 1fr)); gap: 12px">
<BizStatistic
v-for="card in goodCards"
:key="card.title"
:title="card.title"
:value="card.value"
:trend="card.trend"
:trend-text="card.text"
:trend-mode="card.mode"
:reverse="card.reverse"
:icon="card.mode === 'good' && !card.reverse ? CircleCheckFilled : WarningFilled"
/>
</div>
<div style="font-size: 13px; color: var(--el-text-color-secondary)">
cn 红涨绿跌(默认);good 涨绿跌红(涨=好);reverse 与 trend-mode 同轴翻转(XOR)——客诉率(good+reverse)下降 18.4% 渲染为绿色利好色
</div>
</div>
</template>
显示代码
精度与前后缀
本月应付总额
¥1,286,420.50
+9.6%环比
支付转化率
3.62%
+0.21%较上月
月末库存量
48213件
-1240较月初
金额两位小数 + ¥ 前缀 + 千分位;百分比
precision 控制小数位;thousand 可关千分位;prefix / suffix 自由组合。<script setup lang="ts">
/** 场景:精度与前后缀——金额两位小数千分位 / 百分比一位小数 / 库存量关闭千分位,prefix 与 suffix 自由组合 */
import { BizStatistic } from 'vue3-ep-biz-lib'
</script>
<template>
<div style="display: grid; grid-template-columns: repeat(3, minmax(200px, 1fr)); gap: 12px; max-width: 820px">
<BizStatistic title="本月应付总额" :value="1286420.5" prefix="¥" :precision="2" trend="up" trend-text="+9.6%" trend-label="环比" />
<BizStatistic title="支付转化率" :value="3.62" :precision="2" suffix="%" trend="up" trend-text="+0.21%" trend-label="较上月" />
<BizStatistic title="月末库存量" :value="48213" suffix="件" :thousand="false" trend="down" trend-text="-1240" trend-label="较月初" />
</div>
</template>
显示代码
数值前缀图标与插槽
会员消费总额
VIP886,213元
+12.8%较上月
周活跃用户
42.7万
本月回收金额
¥68,420
+5.4%环比
#prefix / #suffix 覆盖前后缀(标签、单位);#value 替换数值区(万级缩写等富展示);#trend 自定义趋势区;#extra 底部扩展入口。<script setup lang="ts">
/** 场景:数值前缀图标与插槽——icon 右上角图标、#prefix/#suffix 前后缀插槽、#value 数值区插槽、#trend 趋势区插槽、#extra 底部扩展 */
import { ElButton, ElIcon, ElTag } from 'element-plus'
import { Coin, TrendCharts, User } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
</script>
<template>
<div style="display: grid; grid-template-columns: repeat(2, minmax(220px, 1fr)); gap: 12px; max-width: 640px">
<BizStatistic title="会员消费总额" :value="886213" :icon="Coin" trend="up" trend-text="+12.8%" trend-label="较上月">
<template #prefix>
<ElTag size="small" type="warning" effect="plain" style="margin-right: 4px">VIP</ElTag>
</template>
<template #suffix>
<span style="font-size: 13px; color: var(--el-text-color-secondary); margin-left: 2px">元</span>
</template>
</BizStatistic>
<BizStatistic title="周活跃用户" :value="427000" :icon="User">
<template #value>
<span style="display: inline-flex; align-items: baseline; gap: 2px">
<span>42.7</span>
<span style="font-size: 13px; color: var(--el-text-color-secondary)">万</span>
</span>
</template>
<template #trend>
<span style="display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--el-color-success)">
<ElIcon><TrendCharts /></ElIcon>
连续 6 周攀升
</span>
</template>
</BizStatistic>
<BizStatistic title="本月回收金额" :value="68420" prefix="¥" trend="up" trend-text="+5.4%" trend-label="环比">
<template #extra>
<ElButton size="small" link type="primary" style="margin-top: 4px; padding: 0">查看回款计划</ElButton>
</template>
</BizStatistic>
</div>
</template>
显示代码
数字滚动动画
GMV(动画)
¥8,912,000
+9.8%较昨日
订单数(对照:无动画)
23,410单
+6.4%较昨日
animation 开启后数值从 0(首次)/ 旧值缓动到新值(easeOutCubic,animation-duration 可调),看板定时刷新时数字滚动而非跳变;右侧为关闭动画的对照卡。<script setup lang="ts">
/** 场景:数字滚动动画——定时刷新数据,数值从旧值缓动到新值(右侧为关闭动画的对照卡) */
import { ref } from 'vue'
import { ElButton } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
const gmv = ref(8912000)
const orders = ref(23410)
const refresh = (): void => {
gmv.value = Math.round(gmv.value * (0.9 + Math.random() * 0.25))
orders.value = Math.round(orders.value * (0.9 + Math.random() * 0.25))
}
</script>
<template>
<div style="display: flex; gap: 16px; align-items: stretch; flex-wrap: wrap; max-width: 820px">
<BizStatistic
title="GMV(动画)"
:value="gmv"
prefix="¥"
animation
:animation-duration="1200"
trend="up"
trend-text="+9.8%"
trend-label="较昨日"
/>
<BizStatistic title="订单数(对照:无动画)" :value="orders" suffix="单" trend="up" trend-text="+6.4%" trend-label="较昨日" />
<div style="display: flex; align-items: center">
<ElButton type="primary" plain :icon="Refresh" @click="refresh">刷新数据</ElButton>
</div>
</div>
</template>
显示代码
实时刷新指标
当前在线设备
1,024台
持平每 2s 刷新
监控场景:每 2s 数值与趋势方向自动更新(trend 随数据涨跌切换)。
<script setup lang="ts">
/** 场景:实时刷新指标——每 2s 数值与趋势方向自动更新(trend 随数据涨跌切换 up/down/flat) */
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
const online = ref(1024)
const trend = ref<'up' | 'down' | 'flat'>('flat')
let timer: ReturnType<typeof setInterval> | null = null
onMounted(() => {
timer = setInterval(() => {
const delta = Math.round(Math.random() * 40 - 18)
trend.value = delta > 0 ? 'up' : delta < 0 ? 'down' : 'flat'
online.value = Math.max(900, online.value + delta)
}, 2000)
})
onBeforeUnmount(() => {
if (timer !== null) clearInterval(timer)
})
</script>
<template>
<div style="max-width: 320px">
<BizStatistic
title="当前在线设备"
:value="online"
suffix="台"
:trend="trend"
:trend-text="trend === 'up' ? '上升中' : trend === 'down' ? '下降中' : '持平'"
trend-label="每 2s 刷新"
/>
</div>
</template>
显示代码
尺寸档位
接警总数(default)
18,234起
+124本周
处置完成率(large)
96.4%
+1.2%本周
12,304 +12.5%8,921 -3.2%99.6% +0.8%
卡片形态 default / large;内联形态 small(表格列)/ default / large(大字号)
卡片形态
default / large(大屏投屏);内联形态另有 small(表格列紧凑档)。<script setup lang="ts">
/** 场景:尺寸档位——卡片 default / large(大屏投屏)与内联 small / default / large 三档对比 */
import { BizStatistic } from 'vue3-ep-biz-lib'
interface SizeCard {
title: string
value: number
precision?: number
suffix: string
trend: 'up' | 'down' | 'flat'
trendText: string
trendLabel: string
size: 'small' | 'default' | 'large'
}
const cards: SizeCard[] = [
{ title: '接警总数(default)', value: 18234, suffix: '起', trend: 'up', trendText: '+124', trendLabel: '本周', size: 'default' },
{ title: '处置完成率(large)', value: 96.4, precision: 1, suffix: '%', trend: 'up', trendText: '+1.2%', trendLabel: '本周', size: 'large' },
]
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 16px; max-width: 820px">
<div style="display: flex; gap: 16px; align-items: stretch; flex-wrap: wrap">
<BizStatistic
v-for="m in cards"
:key="m.title"
:title="m.title"
:value="m.value"
:precision="m.precision ?? 0"
:suffix="m.suffix"
:trend="m.trend"
:trend-text="m.trendText"
:trend-label="m.trendLabel"
:size="m.size"
/>
</div>
<div style="display: flex; gap: 24px; align-items: center; flex-wrap: wrap; font-size: 14px">
<BizStatistic inline size="small" value="12,304" :rate="12.5" />
<BizStatistic inline value="8,921" :rate="-3.2" />
<BizStatistic inline size="large" value="99.6%" :rate="0.8" />
</div>
<div style="font-size: 13px; color: var(--el-text-color-secondary)">
卡片形态 default / large;内联形态 small(表格列)/ default / large(大字号)
</div>
</div>
</template>
显示代码
周环比对比卡
本周 GMV
¥186,420
+8.2%较上周
本周新客
1,284人
-3.1%较上周
运营场景:本周 vs 上周双卡,涨跌各配色 + 图标箭头,prefix/suffix 按指标差异配置。
<script setup lang="ts">
/** 场景:周环比对比卡——本周 vs 上周双卡,涨跌各配色 + 图标箭头,prefix/suffix 按指标差异配置 */
import { CaretBottom, CaretTop } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
interface CompareCard {
title: string
value: number
prefix?: string
suffix?: string
ratio: number
}
const cards: CompareCard[] = [
{ title: '本周 GMV', value: 186420, prefix: '¥', ratio: 8.2 },
{ title: '本周新客', value: 1284, suffix: '人', ratio: -3.1 },
]
</script>
<template>
<div style="display: grid; grid-template-columns: repeat(2, minmax(220px, 1fr)); gap: 12px; max-width: 560px">
<BizStatistic
v-for="card in cards"
:key="card.title"
:title="card.title"
:value="card.value"
:prefix="card.prefix ?? ''"
:suffix="card.suffix ?? ''"
:trend="card.ratio >= 0 ? 'up' : 'down'"
:trend-text="`${card.ratio >= 0 ? '+' : ''}${card.ratio}%`"
trend-label="较上周"
:icon="card.ratio >= 0 ? CaretTop : CaretBottom"
/>
</div>
</template>
显示代码
inline 内联基础与同比/环比双指标
12,304 +12.5%8,921 -3.2%99.6% 0.0%1,024ms +2.60%
今日成交额(GMV)
¥86,420
同比 +18.6%环比 -2.3%
本周新客数
1,286
同比 -4.1%环比 +6.8%
平均配送时长
38 分钟
同比 -9.8%环比 +1.2%
inline 内联形态(原 BizTrend):方向按 rate 正负自动推导(0 持平),digits 控制小数位、arrow 关箭头;不传 value 即纯变化率组合,#value 插槽替换数值区。<script setup lang="ts">
/** 场景:inline 内联基础与同比/环比双指标——数值 + 箭头 + 变化率一行展示(原 BizTrend 形态),方向按 rate 正负自动推导 */
import { ElIcon } from 'element-plus'
import { TrendCharts } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
const cardStyle =
'display: flex; flex-direction: column; gap: 10px; padding: 16px 20px; border: 1px solid var(--el-border-color-lighter); border-radius: 8px; flex: 1; min-width: 180px'
const labelStyle = 'font-size: 13px; color: var(--el-text-color-secondary)'
const numStyle = 'font-size: 22px; font-weight: 600'
const duoStyle = 'display: flex; gap: 18px; font-size: 12px'
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 14px">
<div style="display: flex; flex-direction: column; gap: 14px">
<BizStatistic inline value="12,304" :rate="12.5" />
<BizStatistic inline value="8,921" :rate="-3.2" />
<BizStatistic inline value="99.6%" :rate="0" />
<BizStatistic inline value="1,024ms" :rate="2.6" :digits="2" size="small" :arrow="false" />
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap">
<div :style="cardStyle">
<div :style="labelStyle">今日成交额(GMV)</div>
<div :style="numStyle">¥86,420</div>
<div :style="duoStyle">
<span>同比 <BizStatistic inline size="small" :arrow="false" :rate="18.6" /></span>
<span>环比 <BizStatistic inline size="small" :arrow="false" :rate="-2.3" /></span>
</div>
</div>
<div :style="cardStyle">
<div :style="labelStyle">本周新客数</div>
<div :style="numStyle">1,286</div>
<div :style="duoStyle">
<span>同比 <BizStatistic inline size="small" :arrow="false" :rate="-4.1" /></span>
<span>环比 <BizStatistic inline size="small" :arrow="false" :rate="6.8" /></span>
</div>
</div>
<div :style="cardStyle">
<div :style="labelStyle">平均配送时长</div>
<div :style="numStyle">38 分钟</div>
<div :style="duoStyle">
<span>同比 <BizStatistic inline size="small" :arrow="false" :rate="-9.8" trend-mode="good" reverse /></span>
<span>环比 <BizStatistic inline size="small" :arrow="false" :rate="1.2" trend-mode="good" reverse /></span>
</div>
</div>
</div>
<BizStatistic inline :rate="13.9">
<template #value>
<span style="display: inline-flex; align-items: center; gap: 6px">
<ElIcon><TrendCharts /></ElIcon>
周活跃用户 42.7 万
</span>
</template>
</BizStatistic>
</div>
</template>
显示代码
inline 内联表格列
el-table 环比列内嵌:size="small" + rate + trend-data 迷你走势,行高紧凑不撑表格。<script setup lang="ts">
/** 场景:inline 内联表格列——el-table 环比列内嵌(箭头 + 变化率 + 迷你走势),size=small 紧凑不撑行高 */
import { ElTable, ElTableColumn } from 'element-plus'
import { BizStatistic } from 'vue3-ep-biz-lib'
interface SkuRow {
name: string
sales: number
mom: number
spark: number[]
}
const rows: SkuRow[] = [
{ name: '家用空气净化器 X3', sales: 1284, mom: 12.5, spark: [18, 24, 21, 30, 28, 36, 44] },
{ name: '智能门锁 S2 Pro', sales: 962, mom: -3.2, spark: [30, 28, 31, 26, 27, 24, 23] },
{ name: '扫地机器人 R7', sales: 731, mom: 8.9, spark: [12, 15, 14, 18, 20, 22, 26] },
{ name: '即热饮水机 W1', sales: 515, mom: -12.6, spark: [26, 24, 22, 21, 19, 17, 15] },
]
</script>
<template>
<ElTable :data="rows" size="small" style="width: 100%">
<ElTableColumn prop="name" label="商品" min-width="170" />
<ElTableColumn prop="sales" label="月销量" width="90" align="right" />
<ElTableColumn label="环比" width="170" align="right">
<template #default="{ row }">
<BizStatistic inline size="small" :rate="row.mom" :trend-data="row.spark" />
</template>
</ElTableColumn>
</ElTable>
</template>
显示代码
sparkline 迷你走势
今日销售额
¥126,430
+12.5%较昨日
累计注册用户
586,000人
+8.9%较上周
客诉率
0.9%
-18.4%较上月
¥3,100 -9.8%2,048 +21.7%订单 6,482 +6.3%
trend-data 传 ≥2 个点即绘制(sparkline 默认 true);第三组内联设置 :sparkline="false" 关闭走势
trend-data 传 ≥2 个点即绘制纯 SVG 走势(sparkline 默认 true,设 false 关闭),卡片形态走势右贴趋势行,颜色随涨跌口径。<script setup lang="ts">
/** 场景:sparkline 迷你走势——卡片形态传入 trend-data 开启纯 SVG 走势(颜色随涨跌口径),内联形态同行展示 */
import { BizStatistic } from 'vue3-ep-biz-lib'
const gmvTrend = [86, 92, 89, 104, 112, 108, 126]
const userTrend = [42, 45, 44, 48, 47, 52, 58]
const refundTrend = [1.8, 1.6, 1.7, 1.4, 1.2, 1.1, 0.9]
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 14px; max-width: 820px">
<div style="display: grid; grid-template-columns: repeat(3, minmax(200px, 1fr)); gap: 12px">
<BizStatistic
title="今日销售额"
:value="126430"
prefix="¥"
:rate="12.5"
trend-label="较昨日"
:trend-data="gmvTrend"
/>
<BizStatistic
title="累计注册用户"
:value="586000"
suffix="人"
:rate="8.9"
trend-label="较上周"
:trend-data="userTrend"
/>
<BizStatistic
title="客诉率"
:value="0.9"
:precision="1"
suffix="%"
:rate="-18.4"
trend-mode="good"
reverse
trend-label="较上月"
:trend-data="refundTrend"
/>
</div>
<div style="display: flex; gap: 24px; align-items: center; flex-wrap: wrap; font-size: 14px">
<BizStatistic inline size="small" value="¥3,100" :rate="-9.8" trend-mode="good" reverse :trend-data="[4200, 4050, 4300, 3800, 3600, 3350, 3100]" />
<BizStatistic inline size="small" value="2,048" :rate="21.7" :trend-data="[18, 26, 22, 35, 30, 44, 52]" />
<BizStatistic inline value="订单 6,482" :rate="6.3" :trend-data="[52, 48, 55, 58, 61, 60, 65]" :sparkline="false" />
</div>
<div style="font-size: 13px; color: var(--el-text-color-secondary)">
trend-data 传 ≥2 个点即绘制(sparkline 默认 true);第三组内联设置 :sparkline="false" 关闭走势
</div>
</div>
</template>
显示代码
reverse 反转语义
月度物流成本
¥3,100
-9.8%较上月
设备故障次数
3次
-42.9%较上月
单位能耗成本
0.86元/件
+1.2%较上月
物流成本(good+reverse)
¥3,100
-9.8%降=绿
物流成本(cn+reverse 对照)
¥3,100
-9.8%翻转=红
物流成本(cn 默认)
¥3,100
-9.8%降=绿
reverse 与 trend-mode 同轴翻转(XOR):good 看板配 reverse 得「降绿升红」;cn 下 reverse 翻转为涨绿跌红(原 BizTrend 行为);cn 默认本身降=绿
reverse 与 trend-mode 同轴翻转(XOR):成本 / 故障率等「降了才好」的指标配 good + reverse 得「降绿升红」;cn + reverse 翻转为涨绿跌红(原 BizTrend 行为);cn 默认本身下降即为绿。<script setup lang="ts">
/** 场景:reverse 反转语义——成本 / 故障率「降了才好」的指标配 good+reverse(降绿升红),cn+reverse 为翻转对照 */
import { Coin, WarningFilled } from '@element-plus/icons-vue'
import { BizStatistic } from 'vue3-ep-biz-lib'
const costTrend = [4200, 4050, 4300, 3800, 3600, 3350, 3100]
const faultTrend = [12, 9, 10, 7, 5, 6, 3]
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 860px">
<div style="display: flex; gap: 16px; flex-wrap: wrap">
<BizStatistic
title="月度物流成本"
:value="3100"
prefix="¥"
:rate="-9.8"
trend-mode="good"
reverse
trend-label="较上月"
:icon="Coin"
:trend-data="costTrend"
/>
<BizStatistic
title="设备故障次数"
:value="3"
suffix="次"
:rate="-42.9"
trend-mode="good"
reverse
trend-label="较上月"
:icon="WarningFilled"
:trend-data="faultTrend"
/>
<BizStatistic
title="单位能耗成本"
:value="0.86"
:precision="2"
suffix="元/件"
:rate="1.2"
trend-mode="good"
reverse
trend-label="较上月"
/>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap">
<BizStatistic title="物流成本(good+reverse)" :value="3100" prefix="¥" :rate="-9.8" trend-mode="good" reverse trend-label="降=绿" />
<BizStatistic title="物流成本(cn+reverse 对照)" :value="3100" prefix="¥" :rate="-9.8" reverse trend-label="翻转=红" />
<BizStatistic title="物流成本(cn 默认)" :value="3100" prefix="¥" :rate="-9.8" trend-label="降=绿" />
</div>
<div style="font-size: 13px; color: var(--el-text-color-secondary)">
reverse 与 trend-mode 同轴翻转(XOR):good 看板配 reverse 得「降绿升红」;cn 下 reverse 翻转为涨绿跌红(原 BizTrend 行为);cn 默认本身降=绿
</div>
</div>
</template>
显示代码
与 BizStatisticGroup 组合 KPI 带
本周销售额
¥186,420
+8.2%较上周
物流成本
¥3,100
-9.8%较上周
客诉率
0.9%
-18.4%较上周
库存周转天数
6.5天
0.0%较上周
BizStatisticGroup 的 items 继承 BizStatistic 全部 props:rate 自动推导方向、trend-data 绘制走势、reverse 反转口径整组透传
BizStatisticGroup 的 items 继承本组件全部 props:rate 自动推导方向、trend-data 走势、reverse 反转口径整组透传,超出屏宽箭头翻页浏览。<script setup lang="ts">
/** 场景:与 BizStatisticGroup 组合 KPI 带——items 全量透传新能力(rate 自动方向 / sparkline 走势 / reverse 反转) */
import { computed, ref } from 'vue'
import { ElRadioButton, ElRadioGroup } from 'element-plus'
import { Coin, Goods, TrendCharts, WarningFilled } from '@element-plus/icons-vue'
import { BizStatisticGroup } from 'vue3-ep-biz-lib'
import type { BizStatisticGroupItem } from 'vue3-ep-biz-lib'
const range = ref<'week' | 'month'>('week')
const dataSource: Record<'week' | 'month', BizStatisticGroupItem[]> = {
week: [
{ key: 'gmv', title: '本周销售额', value: 186420, prefix: '¥', icon: TrendCharts, rate: 8.2, trendLabel: '较上周', trendData: [15.2, 16.1, 15.8, 17.0, 17.6, 18.0, 18.6] },
{ key: 'cost', title: '物流成本', value: 3100, prefix: '¥', icon: Coin, rate: -9.8, trendMode: 'good', reverse: true, trendLabel: '较上周', trendData: [4200, 4050, 4300, 3800, 3600, 3350, 3100] },
{ key: 'complaint', title: '客诉率', value: 0.9, precision: 1, suffix: '%', icon: WarningFilled, rate: -18.4, trendMode: 'good', reverse: true, trendLabel: '较上周' },
{ key: 'stock', title: '库存周转天数', value: 6.5, precision: 1, suffix: '天', icon: Goods, rate: 0, trendLabel: '较上周' },
],
month: [
{ key: 'gmv', title: '本月销售额', value: 812400, prefix: '¥', icon: TrendCharts, rate: 12.6, trendLabel: '较上月', trendData: [52, 58, 55, 63, 68, 74, 81] },
{ key: 'cost', title: '物流成本', value: 12800, prefix: '¥', icon: Coin, rate: -6.2, trendMode: 'good', reverse: true, trendLabel: '较上月', trendData: [15200, 14800, 15100, 14200, 13800, 13300, 12800] },
{ key: 'complaint', title: '客诉率', value: 0.7, precision: 1, suffix: '%', icon: WarningFilled, rate: -22.5, trendMode: 'good', reverse: true, trendLabel: '较上月' },
{ key: 'stock', title: '库存周转天数', value: 5.8, precision: 1, suffix: '天', icon: Goods, rate: -0.7, trendMode: 'good', reverse: true, trendLabel: '较上月' },
],
}
const items = computed(() => dataSource[range.value])
</script>
<template>
<div style="max-width: 880px">
<ElRadioGroup v-model="range" style="margin-bottom: 12px">
<ElRadioButton value="week">近 7 天</ElRadioButton>
<ElRadioButton value="month">近 30 天</ElRadioButton>
</ElRadioGroup>
<BizStatisticGroup :items="items" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
BizStatisticGroup 的 items 继承 BizStatistic 全部 props:rate 自动推导方向、trend-data 绘制走势、reverse 反转口径整组透传
</div>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| title | string | '' | 指标标题(卡片形态,#title 插槽优先;内联形态不渲染) |
| value | number | string | — | 数值(number 走精度/千分位格式化,string 原样,两形态一致) |
| precision | number | 0 | 小数位(value 为 number 时生效) |
| thousand | boolean | true | 千分位(value 为 number 时生效) |
| prefix / suffix | string | — | 数值前缀(如 '¥')/ 后缀(如 '台') |
| icon | Component | — | 右上角图标(卡片形态) |
| loading | boolean | false | 加载骨架(数值区,两形态均支持) |
| trend | 'up' | 'down' | 'flat' | — | 趋势方向;缺省按 rate 正负推导 |
| trend-text | string | — | 趋势文案(缺省按 rate 格式化,再缺省渲染 ↑/↓/→) |
| trend-label | string | — | 对比基准(如 '较昨日') |
| trend-mode | 'cn' | 'good' | 'cn' | 涨跌配色口径:红涨绿跌 / 涨绿跌红 |
| rate | number | string | — | 变化率(百分数,12.5 → +12.5%),方向按正负自动推导 |
| digits | number | 1 | 变化率保留小数位 |
| arrow | boolean | true | 是否显示涨跌箭头(卡片 ↑/↓/→ 字符、内联箭头图标) |
| reverse | boolean | false | 涨跌语义反转(与 trend-mode 同轴 XOR):cn 下翻转等效 good(涨绿跌红);good 下翻回降绿升红 |
| inline | boolean | false | 内联形态(原 BizTrend):数值 + 箭头 + 变化率 + 迷你走势一行展示 |
| sparkline | boolean | true | 迷你走势开关(配合 trend-data ≥2 点绘制,卡片形态也可开) |
| trend-data | number[] | — | 迷你走势数据(纯 SVG 零依赖) |
| animation | boolean | false | 数值滚动动画(0/旧值缓动到新值) |
| animation-duration | number | 1000 | 滚动动画时长 ms |
| size | 'small' | 'default' | 'large' | 'default' | 尺寸档位(small 紧凑 / large 大屏) |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| — | — | 无自定义事件(原生事件经 attrs 透传根节点,如 @click) |
Slots
| 插槽名 | 说明 |
|---|---|
| title / icon / prefix / suffix | 覆盖对应区域(两形态共用) |
| value | 替换数值区(图标 + 文本等富展示,原 BizTrend #value 能力) |
| trend | 趋势行追加内容(卡片形态) |
| extra | 底部扩展区(处理入口等,卡片形态) |
Expose
| 属性/方法 | 说明 |
|---|---|
| — | 无暴露实例 |