226 lines
4.4 KiB
Vue
226 lines
4.4 KiB
Vue
<template>
|
|
<view class="progress-bar">
|
|
<view class="progress-bar-title" :style="titleStyle">{{ title }}</view>
|
|
|
|
<view v-if="!secondValue" class="bar">
|
|
<view
|
|
class="bar-single"
|
|
:style="{
|
|
backgroundColor: backColor,
|
|
borderRadius: barRadius,
|
|
height: barHeight,
|
|
lineHeight: barHeight
|
|
}"
|
|
>
|
|
<view
|
|
class="bar-content"
|
|
:style="{ width: firstWidth, minWidth: minWidth }"
|
|
>
|
|
<view
|
|
:class="{ 'bar-content-inner': animationReal }"
|
|
:style="{ background: contentColor }"
|
|
>
|
|
<text
|
|
v-if="textPosition === 'inside'"
|
|
class="bar-text"
|
|
:style="{ color: textColor, fontSize: textSize }"
|
|
>
|
|
{{ singleText }}
|
|
</text>
|
|
<text v-else class="placeholder">1</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
v-if="textPosition === 'outside'"
|
|
class="bar-text"
|
|
:style="{ color: textColor, fontSize: textSize }"
|
|
>
|
|
{{ total == 0 ? '100%' : singleText }}
|
|
</view>
|
|
</view>
|
|
|
|
<view v-else class="bar">
|
|
<view
|
|
class="bar-single bar-double"
|
|
:style="{
|
|
backgroundColor: backColor,
|
|
borderRadius: barRadius,
|
|
height: barHeight,
|
|
lineHeight: barHeight
|
|
}"
|
|
>
|
|
<view
|
|
class="bar-content"
|
|
:style="{ width: firstWidth, minWidth: minWidth }"
|
|
>
|
|
<view
|
|
:class="{ 'bar-content-inner': animationReal }"
|
|
:style="{ background: contentColor }"
|
|
>
|
|
<text
|
|
v-if="textPosition !== 'none'"
|
|
class="bar-text"
|
|
:style="{ color: textColor, fontSize: textSize }"
|
|
>
|
|
{{ singleText }}
|
|
</text>
|
|
<text v-else class="placeholder">1</text>
|
|
</view>
|
|
</view>
|
|
<view class="bar-interval placeholder">1</view>
|
|
<view
|
|
class="bar-content"
|
|
:style="{ width: secondWidth, minWidth: minWidth }"
|
|
>
|
|
<view
|
|
:class="{ 'bar-content-inner': animationReal }"
|
|
:style="{ background: contentColor2 }"
|
|
>
|
|
<text
|
|
v-if="textPosition !== 'none'"
|
|
class="bar-text"
|
|
:style="{ color: textColor, fontSize: textSize }"
|
|
>
|
|
{{ doubleText }}
|
|
</text>
|
|
<text v-else class="placeholder">1</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import props from './props.js';
|
|
|
|
export default {
|
|
mixins: [props],
|
|
data() {
|
|
return {
|
|
singleText: '',
|
|
doubleText: '',
|
|
firstWidth: '',
|
|
secondWidth: '',
|
|
animationReal: false
|
|
};
|
|
},
|
|
watch: {
|
|
firstValue: {
|
|
handler(newVal) {
|
|
// 进度条长度改变后,重新加载动画
|
|
if (this.animationReal) {
|
|
this.animationReal = false;
|
|
this.firstWidth = this.manageWidth(0, 'singleText');
|
|
setTimeout(() => {
|
|
this.animationReal = true;
|
|
this.firstWidth = this.manageWidth(
|
|
newVal,
|
|
'singleText'
|
|
);
|
|
}, 100);
|
|
} else {
|
|
this.firstWidth = this.manageWidth(newVal, 'singleText');
|
|
}
|
|
},
|
|
immediate: true
|
|
},
|
|
secondValue: {
|
|
handler(newVal) {
|
|
if (this.animationReal) {
|
|
this.animationReal = false;
|
|
this.secondWidth = this.manageWidth(0, 'doubleText');
|
|
setTimeout(() => {
|
|
this.animationReal = true;
|
|
this.secondWidth = this.manageWidth(
|
|
newVal,
|
|
'doubleText'
|
|
);
|
|
}, 100);
|
|
} else {
|
|
this.secondWidth = this.manageWidth(newVal, 'doubleText');
|
|
}
|
|
},
|
|
immediate: true
|
|
},
|
|
animation: {
|
|
handler(newVal) {
|
|
this.animationReal = newVal;
|
|
},
|
|
immediate: true
|
|
}
|
|
},
|
|
methods: {
|
|
manageWidth(target, flag) {
|
|
let value =
|
|
((target / this.total) * 100).toFixed(this.precision) + '%';
|
|
this.percentum ? (this[flag] = value) : (this[flag] = target);
|
|
// 减去间隔所占宽度
|
|
this.secondValue ? (value = `calc(${value} - 1px)`) : '';
|
|
return value;
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.progress-bar {
|
|
&-title {
|
|
font-size: 4vw;
|
|
font-weight: bold;
|
|
margin-bottom: 1vw;
|
|
}
|
|
|
|
.bar {
|
|
/* #ifdef H5 */
|
|
cursor: pointer;
|
|
/* #endif */
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
|
|
&-single {
|
|
overflow: hidden;
|
|
width: 100vw;
|
|
}
|
|
|
|
&-double {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: left;
|
|
}
|
|
|
|
&-content {
|
|
&-inner {
|
|
animation: addWidth 1.5s 0s;
|
|
}
|
|
}
|
|
|
|
&-interval {
|
|
background-color: #ffffff;
|
|
width: 2px;
|
|
}
|
|
|
|
&-text {
|
|
margin: 0 5px;
|
|
font-size: 4vw;
|
|
}
|
|
|
|
.placeholder {
|
|
color: rgba(0, 0, 0, 0);
|
|
font-size: 4vw;
|
|
}
|
|
}
|
|
}
|
|
|
|
@keyframes addWidth {
|
|
from {
|
|
width: 0;
|
|
}
|
|
to {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|