Download - Vue.js でタイマーを作る
仕様
(カウントダウン)タイマー
時間を設定し, カウントダウンを開始する
フレーム⇔秒 変換機能 60フレーム == 1秒
メインタイマーが開始する前に別途メインタイマー開始待機用のタ
イマー(待機タイマー)を設けるn秒待機してから(メインタイマーの)カウントダウン開始する機能
エメタイマーの機能を再現するだけ
今日紹介する話題
Vue.js (メイン)
vuelidate
window.requestAnimationFrame
Fetch API
Web Audio API
時間がないのでちょっとだけ...
Vue.js とはユーザーインターフェイスを構築するためのプログレッシブフレー
ムワークです。 https://jp.vuejs.org/v2/guide/#はじめに
仮想DOMのサポート (Vue.js v2 以降)新しいDOMと古いDOMを比較し, 差分のみを更新する
新しいDOMで全てを置き換える(更新する)よりもDOM操作の回数が少なくなる
参考: ReactとFluxのこと // Speaker Deck:https://speakerdeck.com/geta6/reacttofluxfalsekoto
リアクティブ(Modelを変更したらDOMが自動で更新される)
ルーティングなどは行わず, Viewのみに焦点を当てている
Reactっぽい
Reactとの違い軽い
ReactはJSX, Vue.jsはTemplateすべての正しいHTMLはテンプレートとしても正しくなる
Pug(旧Jade), Slim, Hamlなどのメタ言語を自由に使える
単一ファイルコンポーネント
Template, ロジック, Styleそれぞれ別々のファイルで管理する
のではなく, 1つのファイル(.vue)で管理するという思想
これら3つの要素は互いに関係しており, 1つのファイルで管理したほうが保守性に優れている...という考え
参考: 他のフレームワークとの比較 ‑ Vue.js:https://jp.vuejs.org/v2/guide/comparison.html
JSX in React
// https://jp.vuejs.org/v2/guide/comparison.htmlrender () { let { items } = this.props let children if (items.length > 0) { children = ( <ul> {items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ) } else { children = <p>項目は見つかりませんでした。</p> } return ( <div className='list-container'> {children} </div> )}
Template in Vue.js
<!-- https://jp.vuejs.org/v2/guide/comparison.html --><template> <div class="list-container"> <ul v-if="items.length"> <li v-for="item in items"> {{ item.name }} </li> </ul> <p v-else>項目は見つかりませんでした。</p> </div></template>
英語らしく読める
JSXほどキモくない
あくまでも極端な例(当然JSXにも利点はある)
単一ファイルコンポーネント
<!-- hello.vue --><template> <p class="message"> {{ msg }} </p></template>
<script>export default { name: 'hello', data() { return { msg: 'Welcome to Your Vue.js App' }; }};</script>
<style scoped>.message { color: red; }</style>
公式Vue.jsテンプレート
github.com/vuejs‑templates/webpack
Vue.jsプロジェクトのプロトタイプを作成してくれるCLIツール
npm install -g vue-cli でインストール
使い方: $ vue init webpack <project> 対話的に作成するプロジェクトの設定を決めていく
プロジェクト構成
.babelrc
.editorconfig
.gitignore
.postcssrc.jsREADME.mdindex.htmlpackage.jsonbuild/ ... 開発サーバやwebpackの設定config/ ... その他設定(環境変数等)node_modules/src/ App.vue ... エントリポイント main.js assets/ ... アセット(画像とか) components/ ... コンポーネント Hello.vuestatic/ ... ???
src/components にコンポーネントを追加していく
時間を表示するコンポーネントを書く
DurationView.vue
mm:ss.ms 形式で残り時間を表示
Template(一部)
<template> <div class="view"> <span>{{ minutes | pad }}分</span> <span>{{ seconds | pad }}秒</span> <span>{{ cs | pad }}</span> </div></template>
ロジック(一部)
<script>export default { name: 'duration-view', props: ['value'], // 0以上の数値 computed: { minutes() { return Math.trunc(this.value / 1000 / 60); }, seconds() { return Math.trunc(this.value / 1000) % 60; }, cs() { return Math.trunc(this.value / 10) % 100; }, }, filters: { pad(value) { // 左側を0詰めして2桁にするフィルタ return value.toString().padStart(2, '0'); }, },};</script>
import DurationView from './DurationView';
export default { name: 'countdown-timer', components: { DurationView, }, data: function () { return { paused: true, ended: true, duration: 0 }; }, ...};</script>
..., methods: { start(duration = this.duration) { if (this.paused) { this.paused = false; this.ended = false; this.updateDuration(duration); // 残り時間を更新 this.startRAFLoop(); // タイマーを起動 } else { this.updateDuration(duration); } this.$emit('start'); // イベント発行 }, stop() { this.updateDuration(0); // 残り時間を0に }, pause() { this.paused = true; // pausedフラグを立てる }, ... }};</script>
肝心のタイマー起動部分
startRAFLoop() { const raf = window.requestAnimationFrame; const cb = (currentTime_ms, prevTime_ms) => { if (this.ended) { this.$emit('pause'); this.$emit('ended'); } else if (this.paused) { this.$emit('pause'); } else { // if this.paused is false, this timer this.updateDuration(this.duration - (currentTime_ms - prevTime_ms)); raf(time_ms => cb(time_ms, currentTime_ms)); } }; const initialTime_ms = window.performance.now(); raf(time_ms => cb(time_ms, initialTime_ms)); },
window.requestAnimationFrame() とは?window.requestAnimationFrame() メソッドは、ブラウザにアニメ
ーションを行いたいことを知らせて、次の再描画の前にアニメーシ
ョンを更新するために指定した関数を呼び出すことを要求します。
このメソッドの引数はひとつで、再描画の前に呼び出すコールバッ
クメソッドです。
描写のタイミングに合わせて登録したコールバック関数が呼び出さ
れる
ハードウェアに優しい
60回/秒
setTimeout, setIntervalよりも短い間隔で呼び出される
その他の機能
他にも色々機能を作ったけど時間がないので省略するよ!
ほとんどの機能は実装済み
https://github.com/mizdra/vue‑test