shop_h5/components/ProgressCircle.vue

88 lines
1.8 KiB
Vue
Raw Normal View History

2025-12-11 15:38:52 +08:00
<template>
<div
:style="{ width: size + 'px', height: size + 'px' }"
class="progress-circle"
>
<svg :width="size" :height="size" viewBox="0 0 100 100">
<circle
class="background"
cx="50"
cy="50"
r="45"
stroke-width="5"
fill="none"
/>
<circle
class="progress"
cx="50"
cy="50"
r="45"
stroke-width="5"
:stroke="color"
fill="none"
stroke-dasharray="282"
:stroke-dashoffset="282 - (computedProgress / 100) * 282"
style="transition: stroke-dashoffset 0.6s"
/>
</svg>
<div class="text" :style="{ fontSize: size / 5 + 'px' }">{{ text }}</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const props = defineProps<{
progress?: number
color?: string
size?: number
text?: string
duration?: number
}>()
// 设置默认值
const defaultProgress = 50
const defaultColor = 'red'
const defaultSize = 100
const defaultDuration = 500
const defaultText = '50%' // 默认文案
const computedProgress = ref(0)
const color = ref(props.color ?? defaultColor) // 使用传入的颜色或默认颜色
const size = ref(props.size ?? defaultSize) // 使用传入的大小或默认大小
const text = ref(props.text ?? defaultText) // 使用传入的文本或默认文本
onMounted(() => {
setTimeout(() => {
computedProgress.value = props.progress ?? defaultProgress
}, props.duration ?? defaultDuration)
})
</script>
<style scoped>
.progress-circle {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
svg {
transform: rotate(-90deg);
}
circle.background {
stroke: #eee;
}
circle.progress {
stroke-linecap: round;
transition: stroke-dashoffset 0.8s ease;
}
.text {
position: absolute;
font-weight: bold;
}
</style>