如何在Vuetify中完成中间百分比值的圆形进度条?

huangapple go评论67阅读模式
英文:

How to complete Vuetify's circular progress bar on middle percentage value?

问题

我正在使用Vuetify的圆形进度条组件,它接受一个value属性,表示当前进度的百分比,当百分比值达到100时,圆圈就完成了。

我的使用案例是创建一个倒计时,我可以设定一个最大百分比值,比如说10,这意味着当值为10时,圆圈应该显示为完成。但我无法想出一种在中间百分比值时让圆圈完成的方法。

是否有可能以某种方式实现这个目标?

以下是我想要我的10值和20值圆圈填充成和100值圆圈一样的示例代码。

注意- 值可以是任何10的倍数,如10、20、30、50等。

<!-- 开始代码片段 -->
<!-- JavaScript代码 -->
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      second_10: 10,
      second_20: 20,
      second_100: 100,
      interval_10: null,
      interval_20: null,
      interval_100: null,
    }
  },
  methods: {
    countDown(val) {
      this[`interval_${val}`] = setInterval(() => {
         if(this[`second_${val}`] == 0) {
           this[`second_${val}`] = val
         } else {
           this[`second_${val}`]--;
         }
      }, 1000)
    },
    stopCountDown() {
      clearInterval(this.interval_10);
      clearInterval(this.interval_20);
      clearInterval(this.interval_100)
    }
  }
})
<!-- HTML代码 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons"/>
<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-row>
        <v-col cols="12" align="center">
          <v-btn small color="error" @click="stopCountDown()">停止计时器</v-btn>
        </v-col>
        <v-col>
          <v-btn small @click="countDown(100)">开始计时器</v-btn>
          <v-progress-circular
            :rotate="360"
            :size="50"
            :width="5"
            :value="second_100"
            color="success"
            class="mt-3"
            >
            {{ second_100 }}
          </v-progress-circular>
        </v-col>
        <v-col>
          <v-btn small @click="countDown(10)">开始计时器</v-btn>
          <v-progress-circular
            :rotate="360"
            :size="50"
            :width="5"
            :value="second_10"
            color="success"
            class="mt-3"
            >
            {{ second_10 }}
          </v-progress-circular>
        </v-col>
        <v-col>
          <v-btn small @click="countDown(20)">开始计时器</v-btn>
          <v-progress-circular
            :rotate="360"
            :size="50"
            :width="5"
            :value="second_20"
            color="success"
            class="mt-3"
            >
            {{ second_20 }}
          </v-progress-circular>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</div>
<!-- 结束代码片段 -->
英文:

I am using Vuetify's progress circular component that takes a value prop which is the percentage of current progress and the circle gets completed when the percentage value reaches 100.
My use case is to create a countdown and I can have a max percentage value of let's say 10, which means the circle should show completed on a value of 10. But I can't figure out a way to complete the circle on the middle percentage value.

Is this possible anyhow?

Here is my example code where I want my 10-value and 20-value circles to be filled like the 100-value circle.

Note- The value could be any multiple of 10, like 10, 20, 30, 50, etc.

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

new Vue({
el: &#39;#app&#39;,
vuetify: new Vuetify(),
data() {
return {
second_10: 10,
second_20: 20,
second_100: 100,
interval_10: null,
interval_20: null,
interval_100: null,
}
},
methods: {
countDown(val) {
this[`interval_${val}`] = setInterval(() =&gt; {
if(this[`second_${val}`] == 0) {
this[`second_${val}`] = val
} else {
this[`second_${val}`]--;
}
}, 1000)
},
stopCountDown() {
clearInterval(this.interval_10);
clearInterval(this.interval_20);
clearInterval(this.interval_100)
}
}
})

<!-- language: lang-html -->

&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.css&quot;/&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://fonts.googleapis.com/css?family=Material+Icons&quot;/&gt;
&lt;div id=&quot;app&quot;&gt;
&lt;v-app id=&quot;inspire&quot;&gt;
&lt;v-container&gt;
&lt;v-row&gt;
&lt;v-col cols=&quot;12&quot; align=&quot;center&quot;&gt;
&lt;v-btn small color=&quot;error&quot; @click=&quot;stopCountDown()&quot;&gt;Stop Timer&lt;/v-btn&gt;
&lt;/v-col&gt;
&lt;v-col&gt;
&lt;v-btn small @click=&quot;countDown(100)&quot;&gt;start timer&lt;/v-btn&gt;
&lt;v-progress-circular
:rotate=&quot;360&quot;
:size=&quot;50&quot;
:width=&quot;5&quot;
:value=&quot;second_100&quot;
color=&quot;success&quot;
class=&quot;mt-3&quot;
&gt;
{{ second_100 }}
&lt;/v-progress-circular&gt;
&lt;/v-col&gt;
&lt;v-col&gt;
&lt;v-btn small @click=&quot;countDown(10)&quot;&gt;start timer&lt;/v-btn&gt;
&lt;v-progress-circular
:rotate=&quot;360&quot;
:size=&quot;50&quot;
:width=&quot;5&quot;
:value=&quot;second_10&quot;
color=&quot;success&quot;
class=&quot;mt-3&quot;
&gt;
{{ second_10 }}
&lt;/v-progress-circular&gt;
&lt;/v-col&gt;
&lt;v-col&gt;
&lt;v-btn small @click=&quot;countDown(20)&quot;&gt;start timer&lt;/v-btn&gt;
&lt;v-progress-circular
:rotate=&quot;360&quot;
:size=&quot;50&quot;
:width=&quot;5&quot;
:value=&quot;second_20&quot;
color=&quot;success&quot;
class=&quot;mt-3&quot;
&gt;
{{ second_20 }}
&lt;/v-progress-circular&gt;
&lt;/v-col&gt;
&lt;/v-row&gt;
&lt;/v-container&gt;
&lt;/v-app&gt;
&lt;/div&gt;

<!-- end snippet -->

答案1

得分: 2

你需要找到一个乘数,从你的初始倒计时值开始,使其达到100。只需执行 counter * (100 / initialCounterValue) 即可获得结果。

唯一的问题在于初始计数值必须是100的倍数。像 18 这样的值将无法正常工作哈哈

我建议创建一个组件,以便将这个逻辑放在一个地方:

&lt;template&gt;
  &lt;v-col&gt;
     &lt;v-btn small @click=&quot;startCountdown&quot;&gt;开始计时器&lt;/v-btn&gt;
     &lt;v-progress-circular
        :rotate=&quot;360&quot;
        :size=&quot;50&quot;
        :width=&quot;5&quot;
        :value=&quot;counter * (100 / from)&quot;
        color=&quot;success&quot;
        class=&quot;ms-4&quot;
     &gt;
       {{ counter }}
     &lt;/v-progress-circular&gt;
   &lt;/v-col&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
  props: {
    from: { type: Number, default: 10 }
  },
  data() {
    return {
       counter: this.from,
       interval: null,
    }
  },
  methods: {
    startCountdown() {
       this.interval = setInterval(() =&gt; {
          if (this.counter &lt;= 0 &amp;&amp; this.interval) {
             clearInterval(this.interval)
          } else {
             this.counter--;
          }
       }, 1000)
    }
  }
}
&lt;/script&gt;

带有公式的示例:

<!-- 开始片段:js 隐藏:false 控制台:false babel: null -->

<!-- 语言: lang-js -->

new Vue({
  el: &#39;#app&#39;,
  vuetify: new Vuetify(),
  data() {
    return {
      second_100: 100,
      second_20: 20,
    }
  },
  methods: {
    countDown(val) {
      setInterval(() =&gt; {
         if(this[`second_${val}`] == 0) {
           this[`second_${val}`] = val
         } else {
           this[`second_${val}`]--;
         }
      }, 1000)
    },
  }
})

<!-- 语言: lang-html -->

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons"/>
<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-row>
        <v-col>
          <v-btn small @click="countDown(100)">开始计时器</v-btn>
          <v-progress-circular
            :rotate="360"
            :size="50"
            :width="5"
            :value="second_100"
            color="success"
            class="ms-4"
            >
            {{ second_100 }}
          </v-progress-circular>
        </v-col>
        <v-col>
          <v-btn small @click="countDown(20)">开始计时器</v-btn>
          <v-progress-circular
            :rotate="360"
            :size="50"
            :width="5"
            :value="second_20 * (100/20)"
            color="success"
            class="ms-4"
            >
            {{ second_20 }}
          </v-progress-circular>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</div>

<!-- 结束片段 -->
英文:

You need to find the multiplier to reach 100 from your initial countdown value. Just do counter * (100 / initialCounterValue) to get it.

This only concern here is that the initial counter value must be a multiple of 100. It won't work well with like 18 haha

I'd suggest to make a component so that this logic is in a single place:

&lt;template&gt;
  &lt;v-col&gt;
     &lt;v-btn small @click=&quot;startCountdown&quot;&gt;start timer&lt;/v-btn&gt;
     &lt;v-progress-circular
        :rotate=&quot;360&quot;
        :size=&quot;50&quot;
        :width=&quot;5&quot;
        :value=&quot;counter * (100 / from)&quot;
        color=&quot;success&quot;
        class=&quot;ms-4&quot;
     &gt;
       {{ counter }}
     &lt;/v-progress-circular&gt;
   &lt;/v-col&gt;
&lt;/template&gt;
&lt;script&gt;
export default {
  props: {
    from: { type: Number, default: 10 }
  },
  data() {
    return {
       counter: this.from,
       interval: null,
    }
  },
  methods: {
    startCountdown() {
       this.interval = setInterval(() =&gt; {
          if (this.counter &lt;= 0 &amp;&amp; this.interval) {
             clearInterval(this.interval)
          } else {
             this.counter--;
          }
       }, 1000)
    }
  }
}
&lt;/script&gt;

Example with the formula:

<!-- begin snippet: js hide: false console: false babel: null -->

<!-- language: lang-js -->

new Vue({
el: &#39;#app&#39;,
vuetify: new Vuetify(),
data() {
return {
second_100: 100,
second_20: 20,
}
},
methods: {
countDown(val) {
setInterval(() =&gt; {
if(this[`second_${val}`] == 0) {
this[`second_${val}`] = val
} else {
this[`second_${val}`]--;
}
}, 1000)
},
}
})

<!-- language: lang-html -->

&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.3.1/dist/vuetify.min.css&quot;/&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://fonts.googleapis.com/css?family=Material+Icons&quot;/&gt;
&lt;div id=&quot;app&quot;&gt;
&lt;v-app id=&quot;inspire&quot;&gt;
&lt;v-container&gt;
&lt;v-row&gt;
&lt;v-col&gt;
&lt;v-btn small @click=&quot;countDown(100)&quot;&gt;start timer&lt;/v-btn&gt;
&lt;v-progress-circular
:rotate=&quot;360&quot;
:size=&quot;50&quot;
:width=&quot;5&quot;
:value=&quot;second_100&quot;
color=&quot;success&quot;
class=&quot;ms-4&quot;
&gt;
{{ second_100 }}
&lt;/v-progress-circular&gt;
&lt;/v-col&gt;
&lt;v-col&gt;
&lt;v-btn small @click=&quot;countDown(20)&quot;&gt;start timer&lt;/v-btn&gt;
&lt;v-progress-circular
:rotate=&quot;360&quot;
:size=&quot;50&quot;
:width=&quot;5&quot;
:value=&quot;second_20 * (100/20)&quot;
color=&quot;success&quot;
class=&quot;ms-4&quot;
&gt;
{{ second_20 }}
&lt;/v-progress-circular&gt;
&lt;/v-col&gt;
&lt;/v-row&gt;
&lt;/v-container&gt;
&lt;/v-app&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月1日 16:09:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75600992.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定