Vuetify进度栏无法同步值

时间:2019-06-21 17:54:54

标签: vue.js vuetify.js

我有一个示例可以复制我的实际操作。当新项目推入数组时,计数器增加,并将其值设置为进度。

对于该示例,我准备了一个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模型显示实际值

2 个答案:

答案 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的工作原理类似。也许有一个更好的公式可以产生更准确的睡眠间隔,但我想不到一个。