| 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>
 |