今度参加するハッカソンでVue3とFirestoreを使うことになったので、練習がてら簡単なゲームを作成してみました。
ゲームの内容は訪問者全員が同じ数字を操作するカウンターゲームです。プラスボタンを押すと数字がインクリメントされ、マイナスボタンを押すと数字がデクリメントされ、リセットボタンを押すと0に戻るようなもを、自分が操作すると他の人の画面にも反映され、同じように他の人が操作した内容がリアルタイムに反映される双方向通信ができるゲームです。
読んで欲しい人
- Vue3とFirestoreを知ってはいるが、使ったことがなくて興味がある人
- Vue3とFirestoreを知っていて、使ってみたい人
事前準備
- プロジェクトを作成して、
firebase init
- Firestoreでcounterコレクションのnumberというnumberタイプのフィールドを持ったドキュメントを作成
- Vue3のセットアップ
- CounterGame.vueという名のコンポーネントを作成し、App.vueファイルで読み込む
作成手順
まずはファイル内で使用する関数をインポートします。
CounterGame.vue
<script setup>
import {
getFirestore,
getDocs,
collection,
onSnapshot,
doc,
setDoc
} from 'firebase/firestore'
import { getApp } from 'firebase/app'
import { onMounted, ref } from 'vue'
<script>
Firestoreにある数字のコレクションを画面に表示させます。
CounterGame.vue
<script setup>
const db = getFirestore(getApp())
const num = null
onMounted(() => {
getDocs(collection(db, 'counter')).then((snapshot) => {
snapshot.forEach((counterNumber) => {
num.value = counterNumber.data().number
})
})
})
</script>
<template>
<span>{{ num }}</span>
</template>
プラスすると、Firestoreの数字のコレクションと表示している数字をインクリメントするようにします。
Firestoreの数字のコレクションをインクリメントします。
CounterGame.vue
<script setup>
const increment = async () => {
await setDoc(doc(db, 'counter', 'counterNumber'), {
number: ++num.value
})
}
</sctipt>
<template>
<button @click="increment">+</button>
</template>
プラスした時に、画面の値が即座に切り替わるようにします。
<script setup>
- const num = null
+ const num = ref()
</script>
プラスした時に他のユーザにも数字がリアルタイムに反映されるようにします。
CounterGame.vue
<script setup>
// データの変更があった時に、numに再代入する
onMounted(() => {
onSnapshot(collection(db, 'counter'), (snapshot) => {
console.log('snapshot', num.value)
snapshot.forEach((counterNumber) => {
num.value = counterNumber.data().number
})
})
})
<script setup>
マイナスとリセットボタンも同じ要領で作成します。
CounterGame.vue
<script setup>
const decrement = async () => {
await setDoc(doc(db, 'counter', 'counterNumber'), {
number: --num.value
})
}
const reset = async () => {
await setDoc(doc(db, 'counter', 'counterNumber'), {
number: 0
})
}
</script>
<template>
<button @click="decrement">-</button>
<button @click="reset">reset</button>
</template>
出来上がり⭐️
最後に
実際に自分は作ってみて、Vue3とFirestoreを使うとこのコードの記述量で双方向通信、非同期処理が可能になるのに感動しました。まだまだVue3やFirestoreの知識が足りないので、頑張って勉強したいと思います。