我有一个示例可以复制我的实际操作。当新项目推入数组时,计数器增加,并将其值设置为进度。
对于该示例,我准备了一个JSFiddle: here
new Vue({
el: '#app',
data () {
return {
valueDeterminate: 0,
total: 1000,
timeOut: 0,
iteraciones: 1000
}
},
methods: {
async Click() {
var arr = [];
var sum = 0;
this.valueDeterminate = 0;
await this.forEach(this.iteraciones, async (i) => {
await this.Sleep(1);
arr.push(1);
sum++;
this.SetProgressBar(sum);
clearTimeout(this.timeOut);
})
},
SetProgressBar(num) {
if (num) {
this.valueDeterminate = Math.round(this.Map(num));
}
},
Map(value) {
return ((value - 0) * (100 - 0)) / (this.total - 0) + 0;
},
async forEach(arr, callback) {
for(let i = 0; i < arr; i++){
await callback(arr[i], i);
}
},
Sleep(milisegundos) {
return new Promise(resolve => this.timeOut = setTimeout(resolve, milisegundos));
},
}
})
只需编辑'total'和'iteraciones'的值(两者必须相同)并运行。如果数字很高,例如1000,则进度没有问题。但是,如果值<= 100,则进度不会同步该值,并且他的v模型显示实际值
答案 0 :(得分:1)
部分问题是进度条上的动画过渡。如果将其包含在CSS中,则一切运行正常:
.v-progress-linear__bar, .v-progress-linear__bar__determinate {
transition: none;
}
虽然足以“修复”它,但这还不是全部。因此,让我们摆脱这种黑客,并进一步挖掘...
下一个问题是,您经常更新进度条,以至于动画过渡不会获得进行的机会。每次更新值时,它将从当前宽度重新开始。因为这种情况会发生在每个“当前”宽度永远不会离开0的帧上。目标宽度会越来越大,但会停留在动画的第一帧上,从而使宽度保持为0。
它在大数值(例如1000)下看起来可以正常工作的原因是由于舍入。几个连续的值将舍入为相同的值,因此实际上没有任何变化,从而使过渡得以进行。但是对于较小的值,您每次都会更新该值,因此动画不能超出该第一帧。
要直接查看舍入的效果,请尝试更改此行:
this.valueDeterminate = Math.round(this.Map(num));
对此:
this.valueDeterminate = this.Map(num);
在运行它之前,请确保删除我之前概述的CSS hack。您会发现进度条现在停滞了,即使总数为1000。如果不将舍入作为缓冲区,我们将以很小的更新轰炸进度条并重置动画过渡。
答案 1 :(得分:0)
我怀疑进度条突然跳动可能与浏览器跟不上Vue对虚拟DOM的快速更新有关。
我认为您可以通过修改睡眠间隔来解决此问题,该间隔应与您的总体或iteraciones有关。定义一个新属性“ sleepInterval”并使用writeable:false
;
...
Object.defineProperty(this, 'sleepInterval', {
value: 4000/this.total,
writeable: false
});
await this.forEach(this.iteraciones, async (i) => {
await this.Sleep(this.sleepInterval);
arr.push(1);
sum++;
this.SetProgressBar(sum);
clearTimeout(this.timeOut);
})
更新JSfiddle:https://jsfiddle.net/skribe/refo9vqn/4/
为什么我将4000
用作股息?因为它似乎在这种情况下工作得很好,所以给了一个睡眠间隔商,以使进度条以令人满意的速度前进。 5000
的工作原理类似。也许有一个更好的公式可以产生更准确的睡眠间隔,但我想不到一个。