Vue.jsでタイマーのコンポーネントをつくる
個人的な趣味で作成しているアプリでタイマー機能が欲しくなったので、
Vue.jsでコンポーネントを作成しました。
コード
Timer.vue
<template>
<div id="timer">
<div class="timer">
<div class="time">
{{ formatTime }}
</div>
<button v-on:click="start" v-if="!timerOn">Start</button>
<button v-on:click="stop" v-if="timerOn">Stop</button>
</div>
</div>
</template>
<script>
export default {
name: 'timer',
data() {
return {
min: 59,
sec: 59,
timerOn: false,
timerObj: null,
}
},
methods: {
count: function() {
if (this.sec <= 0 && this.min >= 1) {
this.min --;
this.sec = 59;
} else if(this.sec <= 0 && this.min <= 0) {
this.complete();
} else {
this.sec --;
}
},
start: function() {
let self = this;
this.timerObj = setInterval(function() {self.count()}, 1000)
this.timerOn = true; //timerがONであることを状態として保持
},
stop: function() {
clearInterval(this.timerObj);
this.timerOn = false; //timerがOFFであることを状態として保持
},
complete: function() {
clearInterval(this.timerObj)
}
},
computed: {
formatTime: function() {
let timeStrings = [
this.min.toString(),
this.sec.toString()
].map(function(str) {
if (str.length < 2) {
return "0" + str
} else {
return str
}
})
return timeStrings[0] + ":" + timeStrings[1]
}
}
}
</script>
<style scoped>
#timer {
display: flex;
align-items: center;
justify-content: center;
}
.time {
font-size: 100px;
}
</style>
解説
data部分
Timer.vue
...
<script>
data() {
return {
min: 59,
sec: 59,
timerOn: false,
timerObj: null,
}
}
...
</script>
min → 分数(Integer)
sec → 秒数(Integer)
timerOn: タイマーのON/OFF(Boolean) ※Start/Stopボタンの表示切り替えに使います
timerObj: setTimeoutちゃんを格納して、timerを止める時に使います。
method部分
Timer.vue
<script>
...
methods: {
// count関数 = setIntervalにより毎秒呼ばれる関数
// ①0秒以下 && 1分を切っていない → 分数を-1、秒を59にリセット
// ②0秒以下 && 0分台 → 終了
// ③それ以外 → 秒数を-1
count: function() {
if (this.sec <= 0 && this.min >= 1) {
this.min --;
this.sec = 59;
} else if(this.sec <= 0 && this.min <= 0) {
this.complete();
} else {
this.sec --;
}
},
start: function() {
let self = this;
this.timerObj = setInterval(function() {self.count()}, 1000)
this.timerOn = true
},
stop: function() {
clearInterval(this.timerObj);
this.timerOn = false
},
complete: function() {
clearInterval(this.timerObj)
}
},
...
</script>
computed部分
Timer.vue
<script>
...
computed: {
formatTime: function() {
let timeStrings = [
this.min.toString(),
this.sec.toString()
].map(function(str) {
if (str.length < 2) {
return "0" + str
} else {
return str
}
})
return timeStrings[0] + ":" + timeStrings[1]
}
...
</script>
分数・秒数が一桁台であれば 01という風に表示するようにstringを操作している。
template部分
Timer.vue
<template>
<div id="timer">
<div class="timer">
<div class="time">
{{ formatTime }}
</div>
<!-- タイマーのON/OFFによってボタンを切り替える -->
<button v-on:click="start" v-if="!timerOn">Start</button>
<button v-on:click="stop" v-if="timerOn">Stop</button>
</div>
</div>
</template>