123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <template>
- <view>
- <view class="flex a-center content" v-if="lineData">
- <view>
- <slot name="content"></slot>
- </view>
- </view>
- <view class="flex a-center" style="padding-right: 10rpx">
- <view
- class="progress-container"
- id="container"
- ref="progressContainer"
- :style="{ background: inBgColor }"
- >
- <view
- class="progress-content flex j-end"
- id="content"
- ref="progressContent"
- :style="{
- height: strokeWidth + 'px',
- background: bgColor,
- width: contentWidth,
- transition: `width ${duration / 1000}s ease`,
- }"
- v-if="isAnimate"
- >
- <view class="textInside flex a-center j-center" v-if="textInside && !noData">
- <view class="text">{{ percentage }}%</view>
- </view>
- </view>
- <view
- v-if="!isAnimate"
- class="progress-content flex j-end"
- :style="{ width: percentage + '%', height: strokeWidth + 'px', background: bgColor }"
- >
- <view class="textInside flex a-center j-center" v-if="textInside && !noData">
- <view class="text">{{ percentage }}%</view>
- </view>
- </view>
- </view>
- <view>
- <view class="percentage" v-if="!textInside && !lineData && !noData && !isAnimate"
- >{{ percentage }}%
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- name: 'AiProgress',
- components: {},
- props: {
- // 进度条的值
- percentage: {
- type: [Number, String],
- required: true,
- },
- // 是否内联显示数据
- textInside: {
- type: Boolean,
- default: false,
- },
- // 进度条高度
- strokeWidth: {
- type: [Number, String],
- default: 6,
- },
- // 默认动画时长
- duration: {
- type: [Number, String],
- default: 2000,
- },
- // 是否有动画
- isAnimate: {
- type: Boolean,
- default: false,
- },
- // 背景颜色
- bgColor: {
- type: String,
- default: 'linear-gradient(90deg, var(--ui-BG-Main) 0%, var(--ui-BG-Main-gradient) 100%)',
- },
- // 是否不显示数据
- noData: {
- type: Boolean,
- default: false,
- },
- // 是否自定义显示内容
- lineData: {
- type: Boolean,
- default: false,
- },
- // 自定义底色
- inBgColor: {
- type: String,
- default: '#ebeef5',
- },
- },
- data() {
- return {
- width: 0,
- timer: null,
- containerWidth: 0,
- contentWidth: 0,
- };
- },
- methods: {
- start() {
- if (this.isAnimate) {
- // #ifdef H5
- this.$nextTick(() => {
- let progressContainer = this.$refs.progressContainer.$el;
- let progressContent = this.$refs.progressContent.$el;
- let style = window.getComputedStyle(progressContainer, null);
- let width = style.width.replace('px', '') * ((this.percentage * 1) / 100);
- progressContent.style.width = width.toFixed(2) + 'px';
- progressContent.style.transition = `width ${this.duration / 1000}s ease`;
- });
- // #endif
- const container = uni.createSelectorQuery().in(this).selectAll('#container');
- const content = uni.createSelectorQuery().in(this).selectAll('#content');
- container.boundingClientRect().exec((res1) => {
- this.contentWidth =
- res1[0][0].width * 1 * ((this.percentage * 1) / 100).toFixed(2) + 'px';
- });
- }
- },
- },
- mounted() {
- this.$nextTick(() => {
- this.start();
- });
- },
- created() {},
- filters: {},
- computed: {},
- watch: {},
- directives: {},
- };
- </script>
- <style scoped lang="scss">
- .content {
- margin-bottom: 10px;
- .c-per {
- font-size: 26px;
- }
- }
- .progress-container {
- width: 100%;
- border-radius: 100px;
- .progress-content {
- border-radius: 100px;
- width: 0;
- }
- .textInside {
- color: #fff;
- margin-right: 10rpx;
- position: relative;
- }
- }
- .text {
- margin-left: 10rpx;
- font-size: 16rpx;
- width: 100rpx;
- color: #FFB9B9;
- }
- .percentage {
- margin-left: 6px;
- font-size: 12px;
- width: 30px;
- }
- .flex {
- display: flex;
- }
- .a-center {
- align-items: center;
- }
- .j-center {
- justify-content: center;
- }
- .j-between {
- justify-content: space-between;
- }
- .content {
- margin-bottom: 10px;
- color: #666;
- font-size: 32rpx;
- }
- </style>
|