pad-app/components/lx-progress-bar/lx-progress-bar.vue

226 lines
4.4 KiB
Vue
Raw Normal View History

2023-11-21 17:43:02 +08:00
<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 }"
>
2024-06-11 17:19:31 +08:00
{{ total == 0 ? '100%' : singleText }}
2023-11-21 17:43:02 +08:00
</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>