【问题标题】:Vuetify progress bar does not synchronize the valueVuetify 进度条不同步值
【发布时间】:2019-11-04 14:15:11
【问题描述】:

我有一个例子可以复制我实际在做的事情。当一个新项目被推入数组时,计数器会增加并将值设置为进度。

例如,我准备了一个 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,则进度没有问题。但是如果值

【问题讨论】:

    标签: vue.js vuetify.js


    【解决方案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。如果没有四舍五入作为缓冲区,我们会用微小的更新轰炸进度条并重置动画过渡。

    【讨论】:

      【解决方案2】:

      我怀疑进度条突然跳动可能跟浏览器跟不上Vue快速更新虚拟DOM有关。

      我认为您可以通过修改与您的总数或迭代次数相关的睡眠间隔来解决此问题。定义一个新属性“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 的工作方式类似。可能有一个更好的公式可以产生更准确的睡眠间隔,但我想不出一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 2018-10-13
        • 1970-01-01
        • 2021-07-08
        相关资源
        最近更新 更多