CircleProgress 环形进度条
17:06说明
环形进度条,用圆环弧长表达 0–100 的进度值。全平台统一使用 canvas 2d 绘制(背景弧与进度弧画在同一画布),percent 变化时按 duration 平滑过渡;默认插槽用于在圆心放置自定义内容(如百分比文字)。
兼容性
| 平台 | 支持情况 |
|---|---|
| App | ✅ 支持 |
| H5 | ✅ 支持 |
| 微信小程序 | ✅ 支持 |
示例
basic
传入 percent 设置进度值,并用默认插槽在圆心放置百分比文字。
查看源码
vue
<template>
<view class="wrap">
<ux-circle-progress :percent="65" type="primary">
<text class="percent">65%</text>
</ux-circle-progress>
</view>
</template>
<style scoped>
.wrap {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px 0;
}
.percent {
font-size: 20px;
font-weight: bold;
color: #303133;
}
</style>type
通过 type 配置 primary / success / warning / error / info 五种主题色,设置后 active-color 失效。
查看源码
vue
<template>
<view class="row">
<view class="item" v-for="(item, index) in typeList" :key="index">
<ux-circle-progress :percent="70" :type="item.type" :width="80">
<text class="percent-small">70%</text>
</ux-circle-progress>
</view>
</view>
</template>
<script setup lang="uts">
const typeList = [
{ type: 'primary', label: 'primary' },
{ type: 'success', label: 'success' },
{ type: 'warning', label: 'warning' },
{ type: 'error', label: 'error' },
{ type: 'info', label: 'info' }
];
</script>
<style scoped>
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
padding: 10px 0 5px;
}
.item {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 15px;
padding: 0 12px;
}
.percent-small {
font-size: 13px;
font-weight: bold;
color: #303133;
}
</style>size
通过 width 设置圆环整体宽度(高度等于宽度),border-width 设置环的线宽,单位均为 px。
查看源码
vue
<template>
<view class="row">
<view class="item">
<ux-circle-progress :percent="60" type="primary" :width="70" :border-width="4">
<text class="percent-small">60%</text>
</ux-circle-progress>
<text class="label">140</text>
</view>
<view class="item">
<ux-circle-progress :percent="60" type="primary" :width="100" :border-width="7">
<text class="percent">60%</text>
</ux-circle-progress>
<text class="label">200</text>
</view>
<view class="item">
<ux-circle-progress :percent="60" type="primary" :width="120" :border-width="12">
<text class="percent-small">60%</text>
</ux-circle-progress>
<text class="label">240</text>
</view>
</view>
</template>
<style scoped>
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
padding: 10px 0 5px;
}
.item {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 15px;
padding: 0 12px;
}
.percent {
font-size: 20px;
font-weight: bold;
color: #303133;
}
.percent-small {
font-size: 13px;
font-weight: bold;
color: #303133;
}
.label {
margin-top: 6px;
font-size: 12px;
color: #c0c4cc;
}
</style>dynamic
percent 为响应式值时,变化会带动画重绘圆环;示例通过按钮增减进度。
查看源码
vue
<template>
<view class="wrap">
<ux-circle-progress :percent="percent" type="success">
<text class="percent">{{ percent + '%' }}</text>
</ux-circle-progress>
</view>
<view class="btn-row">
<view class="btn" @click="reduce">
<text class="btn-text">-</text>
</view>
<text class="btn-value">{{ percent + '%' }}</text>
<view class="btn" @click="add">
<text class="btn-text">+</text>
</view>
</view>
</template>
<script setup lang="uts">
const percent = ref<number>(65);
function add(): void {
percent.value = Math.min(percent.value + 10, 100);
}
function reduce(): void {
percent.value = Math.max(percent.value - 10, 0);
}
</script>
<style scoped>
.wrap {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px 0;
}
.percent {
font-size: 20px;
font-weight: bold;
color: #303133;
}
.btn-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.btn {
width: 40px;
height: 40px;
border-radius: 40px;
background-color: #2979ff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.btn-text {
font-size: 22px;
color: #ffffff;
line-height: 22px;
}
.btn-value {
font-size: 18px;
font-weight: bold;
color: #303133;
margin: 0 20px;
min-width: 60px;
text-align: center;
}
</style>custom
通过 active-color / inactive-color 自定义激活色与底色,bg-color 设置组件背景色,duration 控制画一圈的动画时长。
查看源码
vue
<template>
<view class="wrap">
<ux-circle-progress
:percent="percent"
:active-color="activeColor"
:inactive-color="inactiveColor"
:bg-color="bgColor"
:duration="duration"
>
<text class="percent">{{ percent + '%' }}</text>
</ux-circle-progress>
</view>
<view class="btn-row">
<view class="btn" @click="reduce">
<text class="btn-text">-</text>
</view>
<text class="btn-value">{{ percent + '%' }}</text>
<view class="btn" @click="add">
<text class="btn-text">+</text>
</view>
</view>
</template>
<script setup lang="uts">
const percent = ref<number>(80);
const activeColor = '#19be6b';
const inactiveColor = '#ebeef5';
const bgColor = '#f4f6f8';
const duration = 2000;
function add(): void {
percent.value = Math.min(percent.value + 10, 100);
}
function reduce(): void {
percent.value = Math.max(percent.value - 10, 0);
}
</script>
<style scoped>
.wrap {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px 0;
}
.percent {
font-size: 20px;
font-weight: bold;
color: #303133;
}
.btn-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.btn {
width: 40px;
height: 40px;
border-radius: 40px;
background-color: #19be6b;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.btn-text {
font-size: 22px;
color: #ffffff;
line-height: 22px;
}
.btn-value {
font-size: 18px;
font-weight: bold;
color: #303133;
margin: 0 20px;
min-width: 60px;
text-align: center;
}
</style>API
Props
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
customStyle | 自定义根节点样式 | UTSJSONObject | - | - |
customClass | 自定义根节点样式类 | string | '' | - |
percent | 圆环进度百分比,0-100 | number | 0 | - |
inactiveColor | 圆环的底色 | string | '' | - |
activeColor | 圆环激活部分颜色 | string | '' | - |
width | 整个圆环组件的宽度,单位 px | number | string | 100 | - |
borderWidth | 圆环的边框宽度,单位 px | number | string | 7 | - |
duration | 整个圆环画一圈的时间,单位 ms | number | string | 1500 | - |
type | 主题类型 | string | '' | - |
bgColor | 整个组件背景颜色 | string | '' | - |
Events
ux-circle-progress 无事件。
Slots
| 插槽名 | 说明 | 版本 |
|---|---|---|
default | 圆心内容(通常放百分比文字),通过绝对定位居中显示 | - |
注意事项
percent会先被钳制到 0–100 再绘制,传入超范围值不会越界。type优先于activeColor:设置type后activeColor失效;两者都不传时回退主题success色。- 组件宽高相等(
height等于width),圆环半径 =width / 2 - borderWidth;请保证borderWidth小于width / 2,否则圆环会退化。 - 圆环由 canvas 2d 绘制,圆心内容需通过默认插槽放入,组件不会自动生成百分比文字(与线型进度条不同)。
duration是画满一圈的耗时,单次动画时长与本次进度增量成正比(例如追加 5% 约耗时duration / 100 × 5ms),并非每次都走满duration。bgColor默认为透明,只有显式传入时才给整个组件上背景色(避免圆环外围出现实心色块)。- 画布上下文通过
uni.createCanvasContextAsync异步获取,首次渲染进度从 0 动画到目标值。