【问题标题】:How do I create a simple 10 seconds countdown in Vue.js如何在 Vue.js 中创建一个简单的 10 秒倒计时
【发布时间】:2019-04-20 12:40:37
【问题描述】:

我想做一个简单的从10到0的倒计时

我使用普通的 javascript 在网上找到了解决方案,但假设我想在 Vue 中进行。 Jquery中的解决方案

Create a simple 10 second countdown

<template>
   {{ countDown }}

</template>

<script>
  export default {
    computed: {
       countDown() {
         // How do i do the simple countdown here?
       }

    }

  }

</script>

如何在 Vue.js 中重新创建相同的功能?

谢谢

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    请检查这是否适合您。

    <template>
       {{ countDown }}
    </template>
    
    <script>
        export default {
            data() {
                return {
                    countDown : 10
                }
            },
            method: {
                countDownTimer() {
                    if(this.countDown > 0) {
                        setTimeout(() => {
                            this.countDown -= 1
                            this.countDownTimer()
                        }, 1000)
                    }
                }
            }
            created: {
               this.countDownTimer()
            }
        }
    </script>
    

    【讨论】:

      【解决方案2】:

      虽然公认的答案很有效,而且很棒,但实际上可以通过使用 Vue.js watchers 以更简单的方式实现它:

      <template>
          {{ timerCount }}
      </template>
      
      <script>
      
          export default {
      
              data() {
                  return {
                      timerCount: 30
                  }
              },
      
              watch: {
      
                  timerCount: {
                      handler(value) {
      
                          if (value > 0) {
                              setTimeout(() => {
                                  this.timerCount--;
                              }, 1000);
                          }
      
                      },
                      immediate: true // This ensures the watcher is triggered upon creation
                  }
      
              }
          }
      
      </script>
      

      使用这种方法的好处是可以通过简单地设置timerCount的值来立即重置定时器。

      如果您想播放/暂停计时器,那么您可以这样实现(注意 - 这不是一个完美的解决方案,因为它会四舍五入到最接近的秒数):

      <template>
          {{ timerCount }}
      </template>
      
      <script>
      
          export default {
      
              data() {
                  return {
                      timerEnabled: true,
                      timerCount: 30
                  }
              },
      
              watch: {
      
                  timerEnabled(value) {
                      if (value) {
                          setTimeout(() => {
                              this.timerCount--;
                          }, 1000);
                      }
                  },
      
                  timerCount: {
                      handler(value) {
      
                          if (value > 0 && this.timerEnabled) {
                              setTimeout(() => {
                                  this.timerCount--;
                              }, 1000);
                          }
      
                      },
                      immediate: true // This ensures the watcher is triggered upon creation
                  }
      
              }
      
              methods: {
      
                  play() {
                      this.timerEnabled = true;
                  },
      
                  pause() {
                      this.timerEnabled = false;
                  }
      
              }
      
          }
      
      </script>
      

      【讨论】:

      • 倒计时一开始不是线性的。
      【解决方案3】:

      这是我为倒数计时器制作的组件:

      <template>
        <div>
          <slot :hour="hour" :min="min" :sec="sec"></slot>
        </div>
      </template>
      
      <script>
      export default {
        props : {
          endDate : {  // pass date object till when you want to run the timer
            type : Date,
            default(){
              return new Date()
            }
          },
          negative : {  // optional, should countdown after 0 to negative
            type : Boolean,
            default : false
          }
        },
        data(){
          return{
            now : new Date(),
            timer : null
          }
        },
        computed:{
          hour(){
            let h = Math.trunc((this.endDate - this.now) / 1000 / 3600);
            return h>9?h:'0'+h;
          },
          min(){
            let m = Math.trunc((this.endDate - this.now) / 1000 / 60) % 60;
            return m>9?m:'0'+m;
          },
          sec(){
            let s = Math.trunc((this.endDate - this.now)/1000) % 60
            return s>9?s:'0'+s;
          }
        },
        watch : {
          endDate : {
            immediate : true,
            handler(newVal){
              if(this.timer){
                clearInterval(this.timer)
              }
              this.timer = setInterval(()=>{
                this.now = new Date()
                if(this.negative)
                  return
                if(this.now > newVal){
                  this.now = newVal
                  this.$emit('endTime')
                  clearInterval(this.timer)
                }
              }, 1000)
            }
          }
        },
        beforeDestroy(){
          clearInterval(this.timer)
        }
      }
      </script>
      

      【讨论】:

      • 嗨@user8805101,当我尝试您的代码时,我收到错误:无效的道具:道具“endDate”的类型检查失败。预期日期,得到值为“2021-11-03 15:23”的字符串。如何从父组件发送日期。
      【解决方案4】:

      使其成为一个组件,以便您可以重复使用它。

      <body>
          <div id="app">
              <counter></counter>
              <counter></counter>
              <counter></counter>
          </div>
          <script>
              Vue.component('counter', {
                  template: '<button v-on:click="countDownTimer()">{{ countDown }}</button>',
                  data: function () {
                      return {
                          countDown: 10,
                          countDownTimer() {
                              if (this.countDown > 0) {
                                  setTimeout(() => {
                                      this.countDown -= 1
                                      this.countDownTimer();
                                  }, 1000)
                              }
                          }
                      }
                  }
              })
      
              const app = new Vue({
                  el: '#app'
              })
          </script>
      </body>
      

      【讨论】:

        【解决方案5】:

        如果有人使用Luxon 的 DateTime 对象而不是原生 JS 的 Date 对象。

        <template>
          <span v-if="timer">
            {{ timeCalculated }}
          </span>
        </template>
        
        <script>
        import { DateTime } from 'luxon'
        
        export default {
          name: 'CountDownTimer',
        
          props: {
            endDate: {
              type: String,
              required: true
            }
          },
        
          data () {
            return {
              now: DateTime.local(),
              timer: null
            }
          },
        
          computed: {
            timeCalculated () {
              const endDateDateTimeObj = DateTime.fromISO(this.endDate)
              const theDiff = endDateDateTimeObj.diff(this.now, ['hours', 'minutes', 'seconds'])
        
              return `${theDiff.hours}:${theDiff.minutes}:${Math.round(theDiff.seconds)}`
            }
          },
        
          watch: {
            endDate: {
              immediate: true,
        
              handler (endDateTimeStr) {
                const endDateTimeObj = DateTime.fromISO(endDateTimeStr)
        
                if (this.timer) {
                  clearInterval(this.timer)
                }
        
                this.timer = setInterval(() => {
                  this.now = DateTime.local()
        
                  if (this.now > endDateTimeObj) {
                    this.now = endDateTimeObj
                    clearInterval(this.timer)
                  }
                }, 1000)
              }
            }
          },
        
          beforeDestroy () {
            clearInterval(this.timer)
          }
        }
        </script>
        

        在我的情况下,endDate 具有 String 类型,因为该值是从 JSON 恢复的。您可以轻松地将其更改为原始的 DateTime 对象。

        【讨论】:

          【解决方案6】:

          使用日期。

          <template>
            <div>{{ time }}</div>
          </template>
          
          <script>
          export default {
            name: 'Timer',
          
            props: ['seconds'],
          
            data: () => ({
              interval: undefined,
              end: new Date(0, 0, 0),
              current: new Date(0, 0, 0, 0, 0, this.seconds)
            }),
          
            computed: {
              time: {
                get() {
                  return this.current.getSeconds();
                },
          
                set(d) {
                  this.current = new Date(0, 0, 0, 0, 0, this.current.getSeconds() + d);
                }
              }
            },
          
            methods: {
              countDown() {
                this.end >= this.current
                  ? clearInterval(this.interval)
                  : (this.time = -1);
              }
            },
          
            created() {
              this.interval = setInterval(this.countDown, 1000);
            }
          };
          </script>
          

          【讨论】:

            猜你喜欢
            • 2012-09-07
            • 2019-06-03
            • 1970-01-01
            • 2020-12-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多