在 CodePen 上使用 Vue.js 构建番茄钟计时器
我关注Scotch.io上的挑战项目有一段时间了,看到一个我特别想尝试做的项目。它是Scotch.io 挑战 #6的番茄钟。我一直想测试一下自己的技能,所以想试试这个。
设置
设置很简单,因为已经有了Codepen(如下),里面已经完成了所有必要的 HTML 和 CSS 工作。主要工作已经完成,是时候开始着手这项挑战的 JavaScript 部分了。
这个 Codepen 无法使用
第一步
我要做的第一件事是使用我需要的所有变量来设置我的数据。
data: {
message: 'Let the countdown begin!!',
timerRunning: false
}
这仅仅是创建了我的消息传递变量,它会根据计时器的状态而变化,并区分计时器处于活动状态和暂停状态。这些状态对于创建与计时器倒计时相关的方法至关重要。
这些方法与按钮的连接非常自然。我需要为每个按钮附加一个点击时运行的方法。需求是四个按钮(开始、暂停、恢复和重置)。
开始按钮会开启倒计时,并进行timerRunning: true
,因为计时器仍在运行。暂停按钮会冻结倒计时,并进行timerRunning: false
。恢复按钮会以当前时间和步速重新开启倒计时,同时进行timerRunning: true
。最后,重置按钮会将倒计时设置为起始数字,并进行timerRunning: false
。
这是与我们刚才讨论的功能相关的方法的原始代码。包括在某些状态下更改消息。
methods: {
timerRun() {
this.timerRunning = true;
this.message = 'Greatness is within sight!!!';
},
timerPause() {
this.message = 'Never quit, keep going!!';
this.timerRunning = false;
},
timerReset() {
this.message = 'Let the countdown begin!!';
this.timerRunning = false;
},
timerCountdown() {
this.timerRunning = true;
}
}
为了更改某些步骤的消息,我将上面显示的方法绑定到下面显示的按钮上,这会触发不同的操作。根据按下的按钮,它可以显示“计时器正在运行”、“计时器已暂停”、“计时器已重置”或“计时器正在运行”。timerRunning
使用 v-if 函数,随着场景的变化,当前显示的按钮配置也会发生变化。这样,按钮的功能就完成了,现在是时候让计时器真正开始工作了。
<div class="buttons">
<button @click="timerRun" v-if="!timerRunning">Start</button>
<button @click="timerPause" v-if="timerRunning">Pause</button>
<button @click="timerReset" v-if="timerRunning">Restart</button>
</div>
当我开始制作计时器时,我意识到我不太懂如何编写倒计时代码,也不理解创建计时器的基本原理。为了学习它的工作原理,我很快尝试制作一个时钟。
我学会了如何以毫秒为单位来执行所有时钟操作,如何逐步显示时间,以及如何显示小时、分钟、秒和毫秒。通过这个业余项目,我学到了很多关于时间管理的知识,比如如何快速前进或后退时间。
我在制作倒计时器时遇到的一个主要问题是时间会持续变化。刚开始制作倒计时器时,每次按下启动/恢复按钮后,倒计时都会逐渐加快。这不符合我的预期,也不利于后续需要恢复的操作。制作完这个时钟后,我找到了一种更一致的触发计时器启动的方法。
data {
interval: null
},
methods: {
timerRun() {
this.timerRunning = true;
this.message = 'Greatness is within sight!!!';
this.interval = setInterval(this.countdownTimer, 1000);
}
timerPause() {
this.message = 'Never quit, keep going!!';
this.timerRunning = false;
clearInterval(this.interval);
},
timerReset() {
this.message = 'Let the countdown begin!!';
this.timerRunning = false;
clearInterval( () => { this.interval; });
}
}
这段代码对于确保倒计时从初始运行到后续恢复的一致性至关重要。现在,当计时器启动时,this.interval
会启动一个新的计时器进行倒计时。暂停并重置时,该变量会被清除,从而暂停倒计时并阻止变量相互叠加。
要让计时器倒计时,我得先理解大量的数学知识,可惜我数学很差。最后,我需要把时间的单位分解成——小时是 60*60*60,分钟是 60*60,毫秒也是 60。所以你需要把毫秒和时间加起来。(如果我解释得不好,请见谅,我的数学很差)。
现在,倒计时的另一个问题是,如何避免出现负数。下面的解释解释了时间不会变成负数的原因(实际上它会变成负数,但我们没有显示出来)。
timerCountdown() {
console.log('Working');
this.timerRunning = true;
this.interval = setInterval(this.updateCurrentTime, 1000);
// Counts down from 60 seconds times 1000.
setInterval( () => {
this.timerMinutes--
}, 60 * 1000)
// Check if seconds at double zero and then make it a 59 to countdown from.
// need another method of checking the number while in the loop and then adding a zero on the number under 10
if(this.timerSeconds === '00'){
this.timerSeconds = 59;
setInterval( () => {
this.timerSeconds--
}, 1000);
} else {
setInterval( () => {
this.timerSeconds--
}, 1000);
}
},
他的解决方案确实涉及到负数。你可以添加一个简单的检查,如果时间<= 0,就可以重置并停止计时器。至于如何让它保持在60秒,这仅仅是个数学问题。他将四舍五入后的分钟数转换成秒数,然后从总时间(以秒为单位)中减去。所以剩下的就是0到60之间的秒数。
这可以用模数来缩短和清除。this.totalTime % 60
这样余数总是会落在0到60之间。
感谢Zammy13回答我的问题。
模数的细分(余数%)。
我的计时器需要 25 分钟,所以我用了这个totalTime: (25 * 60)
。这等于总时间(25 分钟)乘以 60,也就是秒数。总时间就是 1500 秒。
computed: {
time: function() {
return this.minutes + " : " + this.seconds;
},
hours: function() {
var milli = this.milliseconds;
// var hrs = new Date().getHours();
// Used getHours() since the below didn't work for me
var hrs = Math.floor((milli / 3600000) % 24);
if (hrs >= 13) { hrs = hrs - 12 }
return hrs >= 10 ? hrs : '0' + hrs;
},
minutes: function() {
var min = Math.floor(this.totalTime / 60);
return min >= 10 ? min : '0' + min;
},
seconds: function() {
var sec = this.totalTime - (this.minutes * 60);
return sec >= 10 ? sec : '0' + sec;
}
}
最后一步是确保你的计时器知道它正在倒计时。这可能是整个过程中最简单的部分,只需检查变量timerRunning == true
,然后删除一毫秒即可。
countdownTimer() {
if (this.timerRunning == true) {
this.totalTime--;
}
}
结尾
这条路很漫长,付出的努力也比我预想的要多得多。最终,我做了一个基础的东西,迫不及待地想做一个功能齐全的东西。它能告诉你番茄工作法的进展,还能让番茄工作法在视觉上更有趣。
挑战的最终代码笔
这个 Codepen 有很多问题,包括加速倒计时。我在我的个人版计时器中修复了这个问题。这样做是为了达到一个目标,那就是挑战截止日期。我自己的高级计时器将会有第二部分。
文章来源:https://dev.to/teekatwo/building-a-pomodoro-timer-with-vuejs-on-codepen-7no