uniapp
复制代码
<template>
<view class="pie-progress">
<view class="progress-container" :style="{ width: config.width + 'rpx', height: config.height + 'rpx' }">
<!-- 使用相同的计算方式 -->
<view class="progress-bg" :style="{
background: `conic-gradient(${config.progress.color} 0, ${config.progress.color} ${config.value}%, ${config.progress.backgroundColor } ${config.value}%, ${config.progress.backgroundColor} 100%)`,
'-webkit-mask': `radial-gradient(transparent 0%, transparent ${config.inner.width * 70}%, #000 ${config.inner.width * 70}%, #000 0)`,
width: config.width + 'rpx',
height: config.height + 'rpx'
}"></view>
<!-- 内圈背景 -->
<view
class="inner-background"
:style="{
width: (config.inner.width * 100) + '%',
height: (config.inner.width * 100) + '%',
backgroundColor: config.inner.backgroundColor
}"
></view>
<!-- 文字内容 -->
<view class="progress-inner flex-c-c">
<view class="progress-text flex-c">
<text
class="value"
v-if="config.valueText && config.valueText.value"
:style="{
color: config.valueText.color,
fontSize: config.valueText.fontSize,
fontWeight: config.valueText.fontWeight
}"
>{{ config.valueText.value }}</text>
<text
class="desc"
v-if="config.descText && config.descText.value"
:style="{
color: config.descText.color,
fontSize: config.descText.fontSize,
fontWeight: config.descText.fontWeight
}"
>{{ config.descText.value }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 配置对象
opts: {
type: Object,
default: () => ({})
}
},
computed: {
config() {
return this.mergeWithDefault(this.opts)
}
},
data() {
return {
defaultConfig: {
// 进度值 (0-100)
value: 0,
width: 200, // 整体宽度 (单位: rpx)
height: 200, // 整体高度 (单位: rpx)
// 进度条配置
progress: {
color: '#0E9BF3', // 进度条颜色
backgroundColor: '#E0E4EB' // 进度条背景色
},
// 值文本
valueText: {
value: "",
color: "#3B3B4D",
fontSize: "28rpx",
fontWeight: "bold",
},
// 描述文本
descText: {
value: "",
color: "#999",
fontSize: "20rpx",
fontWeight: "normal"
},
// 内圈配置
inner: {
width: 0.8, // 内圈宽度占比 (0-1) 占比越大内圈越大,进度条越细
backgroundColor: "transparent" // 内圈背景色
}
}
}
},
methods: {
// 合并函数
mergeWithDefault(opts) {
if (!opts || typeof opts !== 'object') {
return { ...this.defaultConfig };
}
const result = {
// 第一层合并
...this.defaultConfig,
...opts,
// 第二层深度合并
progress: {
...this.defaultConfig.progress,
...(opts.progress || {})
},
valueText: {
...this.defaultConfig.valueText,
...(opts.valueText || {})
},
descText: {
...this.defaultConfig.descText,
...(opts.descText || {})
},
inner: {
...this.defaultConfig.inner,
...(opts.inner || {})
}
}
return result
}
}
}
</script>
<style lang="scss">
.pie-progress {
.progress-container {
position: relative;
.progress-bg {
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
}
.inner-background {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
z-index: 1;
}
.progress-inner {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
.progress-text {
flex-direction: column;
flex-shrink: 0;
.value {
font-weight: bold;
}
}
}
}
}
</style>
uniapp
复制代码
<template>
<view>
......
<MDPieProgress :opts="getPieProgressConfig(item)"></MDPieProgress>
</view>
</template>
<script>
export default {
methods: {
getPieProgressConfig(item) {
return {
value:item.rate,
width: 108,
height: 108,
progress: {
color: isSub ? '#FF451C' : '#0E9BF3',
backgroundColor: '#E0E4EB'
},
valueText: {
value: `${item.rate}%`,
color: '#3B3B4D',
fontSize: '28rpx',
fontWeight: 'bold'
},
descText: {
value: '达成率',
color: '#999999',
fontSize: '20rpx',
fontWeight: 'normal'
},
inner: {
width: 0.8,
backgroundColor: '#FFFFFF'
}
}
},
}
}
</script>