// LoadingProgress.vue
<script setup lang="ts">
import { watch, ref, onBeforeMount } from "vue";
import { Progress } from "ant-design-vue";
const props = defineProps<{ loading: boolean }>();
const baseClass = "loading-process";
const initStep = 5;
const range: Record<string, number> = {
0: 6,
10: 5,
20: 4,
30: 3,
40: 2,
50: 1,
60: 0.5,
70: 0.1,
80: 0.05,
90: 0.01,
};
let timeout: null | number = null;
const show = ref(true);
const percent = ref(0);
let step = initStep;
const frequency = 30;
watch(
() => props.loading,
(value: boolean) => {
if (value) {
show.value = true;
percentHandle();
} else {
percent.value = 100;
const selfTimeout = setTimeout(() => {
percent.value = 0;
show.value = false;
clearTimeout(selfTimeout);
if (timeout) {
clearTimeout(timeout);
}
}, 1000);
}
},
);
onBeforeMount(() => {
if (timeout) {
clearTimeout(timeout);
}
});
function percentHandle() {
percent.value += step;
step = range[(parseInt((percent.value / 10).toString()) * 10).toString()];
if (percent.value > 95) {
step = 0.001;
}
if (percent.value > 98) {
step = 0.0001;
}
if (percent.value > 100) {
percent.value = 100;
}
if (props.loading) {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => percentHandle(), frequency);
}
}
</script>
<template>
<div :class="baseClass" v-show="show">
<Progress :percent="percent" :show-info="false" size="small" />
</div>
</template>
<style lang="scss">
$rootClass: "loading-process";
$height: 2px;
.#{$rootClass} {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: -4px;
height: $height;
display: flex;
align-items: center;
> .ant-progress {
div {
height: $height !important;
line-height: $height;
}
.ant-progress-inner {
background-color: transparent !important;
}
}
}
</style>
思路:
接收一个loading属性来控制进度条的显示
监听loading的变化,为true,就用定时器不停的循环使percent不断增加,当为false,把定时器清除,进度条也隐藏
项目中对进度条的需求不是一次性的,而是根据父组件的情况要多次出现进度条,所以当loading为false后,还得做一些重置操作