Vueで最初に作ったものがなぜかデジタル時計だったお話
Vueで最初に作ったものがなぜかデジタル時計だったお話:
Vueに触れ始めて少し経ったある日、
「Vueも少しずつ慣れてきたし、何か一つ自分で作ってみようかな。
でもそんなに難しいのはまだ無理だし…。
とりあえず時計作るか!!」
というわけでこんな感じのものができました。
少々ネタではありますが、学んだことを織り交ぜながら紹介していこうと思います。
図のようにコンポーネントを作って組み合わせていきます。
オンで光ってオフで消える「光る棒!!」を作ります。
縦棒と横棒を選べるようにしておきます。
光る棒を組み合わせて数字の形を作ります。
あとは数字に合わせて「光棒何号」を光らせるかを決めるだけです。
「1」なら「いけ!!3号!!6号!!」といった具合です。
ただの区切りです。ハイ。
NumberPanelとSeparationを並べて時計の形を作ります。
あとは時刻の各値をNumberPanelに割り当てればOKです。
時刻の取得については別途解説します。
時計を実装するために一定間隔で時刻を取得する必要があります。
その時に使用するのがsetIntervalです。
javascriptで日付処理を容易にするためのライブラリです。
今回はフォーマットで使用しています。
これ以上はすみませんが割愛します。
vue-momentというのもあるみたいです。
詳しくは見ていません。ハイ。
フロント学び始めたばかりだけど自由度が高くて楽しい!!でも難しい!!
今回のももっといい方法があるかもしれませんが、棒を光らせたい!!という思いでこんな感じになってしまいました。
次はもっといいものを作りたいですね。
Vueに触れ始めて少し経ったある日、
「Vueも少しずつ慣れてきたし、何か一つ自分で作ってみようかな。
でもそんなに難しいのはまだ無理だし…。
とりあえず時計作るか!!」
というわけでこんな感じのものができました。
少々ネタではありますが、学んだことを織り交ぜながら紹介していこうと思います。
構成図
図のようにコンポーネントを作って組み合わせていきます。
LightStick
オンで光ってオフで消える「光る棒!!」を作ります。縦棒と横棒を選べるようにしておきます。
LightStick.vue
<template> <div class="stick" :class="[type, {light: light}]" /> </template> <script> export default { props: { type: { typs: String, default: 'vertical' } }, data() { return { light: false } }, methods: { on() { this.light = true }, off() { this.light = false } } } </script> <style scoped> .stick { background-color: rgba(200,255,200,0.2); border-radius: 10px; } .vertical { height: 50px; width: 10px; } .horizontal { height: 10px; width: 50px; } .light { background-color: yellowgreen; } </style>
NumberPanel
光る棒を組み合わせて数字の形を作ります。あとは数字に合わせて「光棒何号」を光らせるかを決めるだけです。
「1」なら「いけ!!3号!!6号!!」といった具合です。
NumberPanel.vue
<template> <div class="number-panel"> <light-stick type="horizontal" class="stick stick1" ref="stick1" /> <light-stick type="vertical" class="stick stick2" ref="stick2" /> <light-stick type="vertical" class="stick stick3" ref="stick3" /> <light-stick type="horizontal" class="stick stick4" ref="stick4" /> <light-stick type="vertical" class="stick stick5" ref="stick5" /> <light-stick type="vertical" class="stick stick6" ref="stick6" /> <light-stick type="horizontal" class="stick stick7" ref="stick7" /> </div> </template> <script> import LightStick from "./LightStick" export default { components: { LightStick }, props: { number: 0 }, watch: { number() { //numberの変更とともに表示 this.display() } }, mounted() { //初期表示設定 this.display() }, methods: { display() { switch(this.number) { case 0: this.zero() break case 1: this.one() break case 2: this.two() break case 3: this.three() break case 4: this.four() break case 5: this.five() break case 6: this.six() break case 7: this.seven() break case 8: this.eight() break case 9: this.nine() break } }, clear() { this.$refs.stick1.off() //子コンポーネントのメソッド呼び出しにはref属性を使用 this.$refs.stick2.off() this.$refs.stick3.off() this.$refs.stick4.off() this.$refs.stick5.off() this.$refs.stick6.off() this.$refs.stick7.off() }, one() { this.clear() this.$refs.stick3.on() this.$refs.stick6.on() }, two() { this.clear() this.$refs.stick1.on() this.$refs.stick3.on() this.$refs.stick4.on() this.$refs.stick5.on() this.$refs.stick7.on() }, three() { this.clear() this.$refs.stick1.on() this.$refs.stick3.on() this.$refs.stick4.on() this.$refs.stick6.on() this.$refs.stick7.on() }, four() { this.clear() this.$refs.stick2.on() this.$refs.stick3.on() this.$refs.stick4.on() this.$refs.stick6.on() }, five() { this.clear() this.$refs.stick1.on() this.$refs.stick2.on() this.$refs.stick4.on() this.$refs.stick6.on() this.$refs.stick7.on() }, six() { this.clear() this.$refs.stick1.on() this.$refs.stick2.on() this.$refs.stick4.on() this.$refs.stick5.on() this.$refs.stick6.on() this.$refs.stick7.on() }, seven() { this.clear() this.$refs.stick1.on() this.$refs.stick3.on() this.$refs.stick6.on() }, eight() { this.clear() this.$refs.stick1.on() this.$refs.stick2.on() this.$refs.stick3.on() this.$refs.stick4.on() this.$refs.stick5.on() this.$refs.stick6.on() this.$refs.stick7.on() }, nine() { this.clear() this.$refs.stick1.on() this.$refs.stick2.on() this.$refs.stick3.on() this.$refs.stick4.on() this.$refs.stick6.on() this.$refs.stick7.on() }, zero() { this.clear() this.$refs.stick1.on() this.$refs.stick2.on() this.$refs.stick3.on() this.$refs.stick5.on() this.$refs.stick6.on() this.$refs.stick7.on() } } } </script> <style scoped> .number-panel { background-color: #222; position: relative; height: 130px; width: 70px; } .stick { position: absolute; } .stick1 { top: 0; left: 10px; } .stick2 { top: 10px; left: 0; } .stick3 { top: 10px; left: 60px; } .stick4 { top: 60px; left: 10px; } .stick5 { top: 70px; left: 0; } .stick6 { top: 70px; left: 60px; } .stick7 { top: 120px; left: 10px; } </style>
Separation
ただの区切りです。ハイ。Separation.vue
<template> <div class="colon"> <div class="circle" /> <div class="circle" /> </div> </template> <style scoped> .circle { background-color: yellowgreen; border-radius: 5px; width: 10px; height: 10px; } .colon { height: 130px; display: flex; flex-direction: column; justify-content: space-around; } </style>
DigitalClock
NumberPanelとSeparationを並べて時計の形を作ります。あとは時刻の各値をNumberPanelに割り当てればOKです。
時刻の取得については別途解説します。
DigitalClock.vue
<template> <div class="clock"> <div class="display"> <number-panel :number="hours2" /> <number-panel :number="hours1" /> <separation /> <number-panel :number="minutes2" /> <number-panel :number="minutes1" /> <separation /> <number-panel :number="seconds2" /> <number-panel :number="seconds1" /> </div> </div> </template> <script> import NumberPanel from "./NumberPanel" import Separation from "./Separation" import moment from "moment" export default { components: { NumberPanel, Separation }, data() { return { time: undefined, intervalId: undefined } }, methods: { setTime() { this.intervalId = setInterval(() => { this.time = new Date() }, 100) } }, mounted() { this.setTime() }, beforeDestroy() { clearInterval(this.intervalId) }, computed: { hours1() { return moment(this.time).format("HH") % 10 }, hours2() { return Math.floor(moment(this.time).format("HH") / 10) }, minutes1() { return moment(this.time).format("mm") % 10 }, minutes2() { return Math.floor(moment(this.time).format("mm") / 10) }, seconds1() { return moment(this.time).format("ss") % 10 }, seconds2() { return Math.floor(moment(this.time).format("ss") / 10) } } } </script> <style scoped> .clock { background-color: #111; filter: drop-shadow(10px 10px 10px rgba(0,0,0,0.6)); padding: 50px; } .display { background-color: #222; display: flex; justify-content: space-between; padding: 10px; width: 600px; } </style>
setInterval
時計を実装するために一定間隔で時刻を取得する必要があります。その時に使用するのがsetIntervalです。
data() { return { intervalId: undefined //1. clearIntervalのためのIDを保持します } }, methods: { do() { //2. 一定間隔で処理を実行するためメソッドを用意します this.intervalId = setInterval(() => { //処理内容 }, 1000) //1秒間隔で処理 } }, mounted() { //3. 上記で用意したメソッドをマウントのタイミングで呼び出します。 // これによりこのコンポーネントは一定間隔で処理を実行することになります。 this.do() }, beforeDestroy() { //4. 使用後はしっかりとクリアする必要があります clearInterval(this.intervalId) }
Moment.js
$npm install moment
今回はフォーマットで使用しています。
これ以上はすみませんが割愛します。
vue-momentというのもあるみたいです。
詳しくは見ていません。ハイ。
おわりに
フロント学び始めたばかりだけど自由度が高くて楽しい!!でも難しい!!今回のももっといい方法があるかもしれませんが、棒を光らせたい!!という思いでこんな感じになってしまいました。
次はもっといいものを作りたいですね。
コメント
コメントを投稿