プロ野球のドラフト会議をやってみたかったので、Vue.jsとFirebaseを使って爆速で作ってみた


第一回ドラフト結果

はじめに

まだまだ拙い部分が多いですが、実際に遊んでみて楽しかったので一旦おっけーってことで記事を書いている次第です。
今後も細々修正&追加していこうと思っているので生暖かい目で見守って頂けると幸いです。

そして「爆速」はほぼ釣りです。Qiitaに投稿するなら書いてみたっかたので。笑
プロ野球ドラフト会議っぽい?感じの流れ遊べるまでで約3時間ぐらいだったので、独断と偏見により「爆速」認定しました。
実際はその後この記事を書くまで3ヶ月ぐらいかかってます。。。
ほぼ5.ダサいコードのリファクタリングに費やしました。。。
コミットから逆算するトータル32時間ぐらいで、体感的にはコード書いてた時間は8時間もなさそうかな?もう少し記録を取っておけばよかった

ドラフト会議をやってみる
遊び方

モチベーション

タイトルにもあるように「プロ野球のドラフト会議がやってみたかった」
やりたい! → ない! → 作ろう!

遊び方

1.ドラフト会議ページへGO!

ドラフト会議ページ

2.Room名入力

3.トップページ※このページはずっと使うので閉じないで下さい

4.「招待」ボタン押下でQRコードが表示されるのでスマホなどで読み込む

5.名前を入力

6.下の表の「選手一覧」の選手をクリック

7.選んだ選手が上の表の「獲得希望選手」に移動する(ここはあくまでも自分用)

8.上の表の「獲得希望選手」の選手をクリックすると確認モーダルが表示されるので「確定」ボタンを押下

9.参加者全員が選択するまで待機

10.全員が選択後、「次巡スタート」ボタンが表示されるので押下

11.それっぽい画像が表示されるので、存分に楽しんだら「次へ」ボタンを押下

12.獲得できると「獲得」表示されるので、存分に楽しんだら「Next」ボタンを押下

13. ⑦に戻る

14.存分に楽しむ

作ったもの(動画)

トップページ

参加者と未選択ユーザーが表示される。全員が選択すると次に進める。Firebase様様

個人ページ

獲得できると「獲得済み選手」に移動して、選択可能選手から消える。Firebase様様再び

作ったもの(図)

後日追加予定

制作の流れ

使ったのは大まかにはこの三つ
Vue.js, Firebase, Bootstrap

1.まずはvue cli3でプロジェクト立ち上げ

ググるとQiitaの記事が何個か出てくるが、割と難しいこと書いてる(独断と偏見)がそんなことよりコマンド2つたたいて、あとはGUIで流れに沿ってけば何とかなる。vue cli3

npm install -g @vue/cli
vue ui

2.Firebase Realtime Databeseと接続

公式が一番分かりやすい

3.Firebase Hostingでweb表示

公式が一番分かりやすい再び

4.プロ野球ドラフト会議っぽい?感じの流れのUIをつくる

ここまでで約3時間
bootstrap-vueでガシガシ実装。
1.table
3.input-group
4.modal
記憶とコミットを漁りながら後日追加予定

5.ダサいコードのリファクタリング

ここにだいぶハマってなかなか時間を使ってしまった。約16時間
computedはリアクティブな依存関係にもとづきキャッシュされることを知ってまず思い付いたのがこれ。
しかしこれだとundefinedになる。ハマった一番の理由はconsoleに1回目はundefinedが出る ⇦ これは分かる。二回目にちゃんんとデータが取れてるのが出るののに、mainDataはundefinedのまま。ふぁっっっっっっ!?

export default {
    name: 'top',
    data () {
        return {
        }
    },
    computed: {
        mainData: function() {
            let data = []
            firebase.database().ref('/data').on('value', function(snapshot) { data = snapshot.val() });
       console.log(data)
            return data
        }
    }
}

なるほど、2回目はreturnしてくれないのね。awaitしよう!
で、次に思いついたのがこれ
これだとmainDataはfunctionになる。 ⇦ そりゃそーだ

mainData: async function() {
    let data = await firebase.database().ref('/data').on('value', function(snapshot) { return snapshot.val() })
    return data
}

awaitの場所を変えてみたりなんやかんやあって、こーなった。Firebaseから取得できるとchashDataに格納される、chashDataに変更があるとmainDataに反映されるって寸法
いまだにこれがベストプラクティスなのか激しく疑問

export default {
    name: 'top',
    data () {
        return {
          chashData: []
        }
    },
    created() {
        let _this = this
        firebase.database().ref('/data').once('value').then( snapshot => _this.chashData = snapshot.val() )
    },
    computed: {
        mainData: function() {
            return this.chashData
        },
    }
}

Firebase


firebase.database().ref('/data').once('value') //一度だけを取得 ⇦ Roomが作られた時に選手データを取得
firebase.database().ref('/data').on('value') //データに変更があったら取得 ⇦ child_changedとchild_added両方なので使ってない
firebase.database().ref('/orders').on( 'child_changed' //下層に変更があったら取得 ⇦ 選択希望選手が選択された時
firebase.database().ref('/users').on( 'child_added' //下層に追加があったら取得 ⇦ ユーザーが参加した時

6.複数組で遊べるようにルーティングとデータ構成の修正

約8時間
記憶とコミットを漁りながら後日追加予定

TODO

1.守備位置表示 ⇦ ヤバいサードがいない!宮崎!既に取られてる。。。サードって誰がいたっけ?うおぉぉぉってなった時にあると嬉しい
=>守備位置はデータ取得元がない上に、シーズン中に複数ポジション守ってる選手の扱いなどが難しいので、「投手」「捕手」「内野」「外野」の4つで分類。
2.終了後にオーダーを組める ⇦ やっぱりせっかくやったなら、みんなであーだこーだ話した方が楽しい
=>打順・守備位置を選択して投票できるように実装
3.そのオーダーが(分かりやすく)比較できる ⇦ 横並びとかで見れた方が分かりやすいだろう
=>見やすいかは微妙だが一応実装
4.ルールの追加(守備位置縛り、 合計年棒  etc) ⇦ 全員外野とかになると面白くない、巨人みたいなチームになって微妙?広島とか西武ってSUGEEEEってなる。笑
5.データを選べる(最新、20○○年、OB etc) ⇦ マー君とかイチローとかも欲しい
6.他の人が選んだ選手が見れる ⇦ 戦略性が上がる?見れない方が面白い説もあるので選べるようにしたい

さいごに

ドラフト会議で遊んでもらえれば幸いです。
出来れば、もっとこうして!とか、ここおかしくね?とか教えてもらえるもっと嬉しいです。