vue实现环形进度
Vue 实现环形进度条的方法
使用 SVG 和 CSS 实现基础环形进度
在 Vue 中可以通过 SVG 的 <circle> 元素结合 CSS 动画实现环形进度条。定义一个计算属性动态调整 stroke-dashoffset 实现进度变化。
<template>
<div class="progress-ring">
<svg width="120" height="120">
<circle
class="progress-ring__background"
stroke="#ddd"
stroke-width="8"
fill="transparent"
r="52"
cx="60"
cy="60"
/>
<circle
class="progress-ring__circle"
stroke="#42b983"
stroke-width="8"
fill="transparent"
r="52"
cx="60"
cy="60"
:style="{
strokeDashoffset: circumference - (progress / 100) * circumference
}"
/>
</svg>
</div>
</template>
<script>
export default {
props: {
progress: {
type: Number,
default: 0,
validator: value => value >= 0 && value <= 100
}
},
data() {
return {
radius: 52,
circumference: 2 * Math.PI * 52
}
}
}
</script>
<style>
.progress-ring__circle {
transition: stroke-dashoffset 0.5s ease;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
</style>
使用第三方库 vue-awesome-progress
安装 vue-awesome-progress 库可以快速实现带动画效果的环形进度条:

npm install vue-awesome-progress
组件使用示例:

<template>
<vue-awesome-progress
type="circle"
:progress="progress"
:size="200"
:strokeWidth="10"
primaryColor="#42b983"
secondaryColor="#eee"
/>
</template>
<script>
import VueAwesomeProgress from "vue-awesome-progress"
export default {
components: { VueAwesomeProgress },
data() {
return { progress: 75 }
}
}
</script>
自定义 Canvas 实现
通过 Canvas 绘制可以实现更灵活的环形进度效果:
<template>
<canvas ref="canvas" width="200" height="200"></canvas>
</template>
<script>
export default {
props: {
progress: { type: Number, default: 0 }
},
mounted() {
this.drawProgress()
},
watch: {
progress() {
this.drawProgress()
}
},
methods: {
drawProgress() {
const canvas = this.$refs.canvas
const ctx = canvas.getContext('2d')
const centerX = canvas.width / 2
const centerY = canvas.height / 2
const radius = 80
const lineWidth = 15
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 绘制背景圆环
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
ctx.strokeStyle = '#eee'
ctx.lineWidth = lineWidth
ctx.stroke()
// 绘制进度圆环
const endAngle = (2 * Math.PI * this.progress) / 100 - Math.PI/2
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI/2, endAngle)
ctx.strokeStyle = '#42b983'
ctx.lineWidth = lineWidth
ctx.lineCap = 'round'
ctx.stroke()
}
}
}
</script>
实现带渐变色和动画的环形进度
结合 SVG 的线性渐变和 CSS 动画可以创建更丰富的视觉效果:
<template>
<div class="gradient-progress">
<svg viewBox="0 0 100 100">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#42b983" />
<stop offset="100%" stop-color="#35495e" />
</linearGradient>
</defs>
<circle cx="50" cy="50" r="45" stroke="#eee" stroke-width="8" fill="none"/>
<circle
cx="50" cy="50" r="45"
stroke="url(#gradient)"
stroke-width="8"
fill="none"
:stroke-dasharray="circumference"
:stroke-dashoffset="circumference - (progress / 100) * circumference"
/>
<text x="50" y="55" text-anchor="middle" font-size="20">{{ progress }}%</text>
</svg>
</div>
</template>
<script>
export default {
props: {
progress: { type: Number, default: 0 }
},
computed: {
circumference() {
return 2 * Math.PI * 45
}
}
}
</script>
<style>
.gradient-progress circle {
transition: stroke-dashoffset 0.8s cubic-bezier(0.4, 0, 0.2, 1);
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
</style>
以上方法提供了从基础到高级的环形进度条实现方案,可根据项目需求选择合适的方式。SVG 方案适合大多数场景,Canvas 方案适合需要复杂交互的情况,第三方库方案则适合快速开发。






