先看效果图,其实很简单,实现圆环的方式有多种,
1,svg实现,
2,css3.0实现,
3,canvas实现,
1,svg实现进度条:效果如下:

代码:SvgProgress.vue
<template>
<div class="LoopProgress" :style="''+width+';'+'height:'+height+';'">
<svg viewBox="0 0 96 96" :class="'svg-circle-progress'+' svg-circle-progress'+colorkey" style=" 96px; height: 96px;">
<circle r="40" cx="48" cy="48" fill="none"
stroke-miterlimit="20" stroke-width="10"
class="svg-progress"
style="stroke-dasharray: 275, 279.602;stroke:#eee;">
</circle>
<circle r="40" cx="48" cy="48" fill="none"
stroke-miterlimit="20" stroke-width="10"
:class="'svg-progress'+' svg-progress'+colorkey"
style="stroke-dasharray: 1, 279.602;stroke:#fdd835;">
</circle>
</svg>
<div class="mask">
<span>{{pvalue}}</span>
<span>{{psymbol}}</span>
</div>
<div class="svg-title">
{{title}}
</div>
</div>
</template>
<script>
import $ from 'jquery';
export default ({
props: ['psymbol','pvalue','progress','color','width','height','title','colorkey'],
data() {
return {
}
},
methods:{
calcProgress(){
let self = this;
self.progress = parseInt(self.progress);
$('.svg-progress'+self.colorkey).css('stroke',self.color);
$('.svg-progress'+self.colorkey).css('stroke-dasharray',(self.progress/100)*250+', 279.602');
}
},
mounted(){
this.calcProgress();
},
// 销毁子组件后重建,避免第一个数据不更新的问题
destroyed() {
// this.$parent.showChart = true;
},
})
</script>
<style scoped>
.LoopProgress{
display:inline-block;
position:relative;
210px;
height:100px;
}
svg:not(:root) {
overflow: hidden;
}
.svg-circle-progress {
position: relative;
transform: rotate(-90deg);
}
.svg-progress{
stroke: #2196f3;
stroke-linecap: round;
transition: all .3s linear;
}
.mask{
position:absolute;
top:23px;
left:24px;
}
.mask span{
font-size:14px;
}
.mask span:first-child{
font-size:34px;
}
.svg-title{
display: inline-block;
105px;
position:absolute;
right:0;
bottom:0;
font-size:14px;
}
</style>
父组件引用:
<svgProgress
:pvalue="value6"
:psymbol="'天'"
:progress='progress6'
:color="'#FFAFAF'"
:width="'210px'"
:height="'100px'"
:title="'本期剩余天数'"
:colorkey="6"
v-if="showP6"
></svgProgress>
2.css3.0实现代码
CssProgress.vue
<template>
<div class="LoopProgress" :style="''+width+';'+'height:'+height+';'">
<!--背景圆-->
<div :class="'circle'+' circle'+colorkey">
<!--左半边圆-->
<div :class="'circle_left'+' circle_left'+colorkey">
<div :class="'clip_left'+' clip_left'+colorkey">
</div>
</div>
<!--右半边圆-->
<div :class="'circle_right'+' circle_right'+colorkey">
<div :class="'clip_right'+' clip_right'+colorkey"></div>
</div>
<div class="mask">
<span>{{progress}}</span>%
</div>
</div>
<div class="circle-title">
{{title}}
</div>
</div>
</template>
<script>
import $ from 'jquery';
export default ({
props: ['progress','color','width','height','title','colorkey'],
data() {
return {
}
},
methods:{
calcProgress(){
let self = this;
self.progress = parseInt(self.progress);
$('.circle'+self.colorkey).css('background-color',self.color);
if(self.progress<=50){
$('.circle_right'+self.colorkey).css('transform','rotate('+(self.progress*3.6)+'deg)');
}else{
$('.circle_right'+self.colorkey).css({
'transform':'rotate(0deg)',
"background":self.color
});
$('.circle_left'+self.colorkey).css('transform','rotate('+((self.progress-50)*3.6)+'deg)');
}
}
},
mounted(){
this.calcProgress();
},
// 销毁子组件后重建,避免第一个数据不更新的问题
destroyed() {
// this.$parent.showChart = true;
},
})
</script>
<style scoped>
.LoopProgress{
display:inline-block;
position:relative;
}
.circle {
100px;
height: 100px;
position: relative;
border-radius: 50%;
/* background: red; */
}
.clip_left,.clip_right{
100px;
height:100px;
position: absolute;
top: 0px;
left: 0px;
z-index:100;
}
.circle_left,.circle_right{
100px;
height:100px;
position: absolute;
border-radius: 50%;
top: 0px;
left: 0px;
background: #eee;
z-index:101;
}
/*出于展示用的改变背景色*/
/* .circle_left{
background: green;
}
.circle_right{
background: pink;
} */
.circle_right,.clip_right {
clip:rect(0,auto,auto,50px);
}
.circle_left,.clip_left{
clip:rect(0,50px,auto,0);
}
/*
*当top和left取值为auto时,相当于0
*当bottom和right取值为auto时,相当于100%
*/
.mask {
76px;
height: 76px;
border-radius: 50%;
left: 12px;
top: 12px;
background: #FFF;
position: absolute;
text-align: center;
line-height: 76px;
font-size: 16px;
z-index:102;
}
/* .circle_right{
transform: rotate(55deg);
} */
.circle-title{
display:inline-block;
position:absolute;
bottom:0;
right:0;
105px;
}
</style>
父组件引用:
<dateTools
:dateToolsKey="1"
:trainDateList="trainDateList"
ref="topDateTools1"
@topDateEvent1="topDateFun1"
></dateTools>
<dateTools
:dateToolsKey="2"
:trainDateList="trainDateList2"
ref="topDateTools2"
@topDateEvent2="topDateFun2"
></dateTools>