【Vue.js】Firebaseのデータを取得してリストを表示させよう

Vue.jsで最初に理解するのに時間がかかったのは、親子間のデータ伝達でした。
今回は自分への理解を兼ねて、Firebaseに保存してあるデータを取得し、そのデータを子に伝達して表示する一連のフローを解説したいと思います。

現在はこれで勉強しております。
とてもいい教材なのでご興味ある方はぜひ。
「Vue.js & FirebaseでTwitterライクなSNSアプリを作ってみよう！」
https://www.techpit.jp/courses/enrolled/601067

---

まずFirebaseでデータを準備します。
Firebaseを開いてコンソールに移動します。
続いて[Database]から、[コレクションを開始]を選択してデータのコレクションを作成し、ドキュメントを作成します。
データは何でも構いませんが、後ほどコンテンツをタイムラインのように表示したいので、

- ユーザーidを示す[uid]
- 日付を示す[date]
- 内容を示す[content]

としておきました。
ドキュメントは3つほど作成しておきます。
<img width="1531" alt="スクリーンショット 2020-02-12 22.38.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364497/a08da4a7-ba1b-083e-90e1-74f8f5d7928f.png">

続いてfirebaseとVueアプリケーションを連携させるために、firebaseでアプリを作成します。
[Project Overview]に戻り、「アプリを追加」→[web]を選んでアプリの名前をつけましょう。
その後表示されるスクリプトをコピーしておきます。

<img width="925" alt="スクリーンショット 2020-02-12 22.50.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364497/d832999f-0f98-ff31-e252-2d6addd50e45.png">


続いてVueのコードに移ります。
Vueのファイルで最初に読み込まれるのは `main.js` で、そこにfirebaseのインポートを行います。
firebaseをインポートし、 `firebase/firestore` もインポートします。
さらに先ほどのスクリプトを参考にfirebaseの初期化を行い、 `Vue.use` でfirebaseを使用可能にします。
firestoreのデータベース処理を簡単にするため、 `vuefire` もインポートします。
最後に、他のファイルにもエクスポートできる形で、firestoreのインスタンスである `db` を宣言します。

```javascript

import Vue from 'vue'
import App from './App.vue'
import router from './router'

import { firestorePlugin } from 'vuefire'
import firebase from 'firebase'
import 'firebase/firestore'

firebase.initializeApp({                
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "t",
  messagingSenderId: "",
  appId: ""
})

Vue.use(firestorePlugin)

export const db = firebase.firestore()

Vue.config.productionTip = false


new Vue({
  router,
  render: function (h) { return h(App) }
}).$mount('#app')

```

さて、ここからが本番です。
今回やりたいことは、 `Home` という親コンポーネントに、 `Item` という子コンポーネントを入れ込み、その子コンポーネントに先ほど登録したデータをリスト表示させる、というものです。
どのように書くと、思ったように表示することができるでしょうか。

firestoreからデータのidを受け取るのは、通常親コンポーネントです。
親コンポーネントがデータを受け取り、それを子コンポーネントに伝達し、それぞれの子コンポーネントがそれにあった表示をすることで画面が作成されます。

なので、今回は `Home` がfirestoreのidを受け取ります。
そのidを受け取ると、そのidを子コンポーネントに伝達します。
親コンポーネントから子コンポーネントにデータを伝達するには、そのデータを `props` オブジェクトに格納する必要があります。
そしてそのidを受け取った子コンポーネントは、そのidに応じたコンテンツを取得します。
コンテンツを取得するためには、子コンポーネントでコンテンツを `data` オブジェクトに格納し、 `firestore` でそのコンテンツをfirestoreの中にあるidを照合することで取得することができます。
最後にそのコンテンツを子コンポーネントに表示すれば、1つのコンテンツを表示することができます。
そしてそれを `v-for` ディレクティブで繰り返せば完成です。

早速書いてみましょう。
`Item.vue` を作成し、その中にfirestoreをインポートします。
同時に、 `main.js` で作成した `db` もインポートします。

```javascript

import { firestore } from 'firebase'
import { db } from '../main'
```

親子のコンポーネントを作成するので、 `export default` の中にオブジェクトを記述します。
子コンポーネントの `props` には親とやり取りするための `id` を格納します。
また、 `data` オブジェクトには、取得して子コンポーネントに表示したいデータであるコンテンツ名（ `twit` という名前にしています）を書きます。

```javascript
export default {
    props:['id'],
    data(){
        return{
            twit: {}
        }
}
```

次に、firestoreと照合して、propsから伝達してきたidと同じidを持つドキュメントを `twit` の中に代入します。
代入するには、以下のように書きます。

```javascript

firestore(){
        return{
            twit: db.collection("twits").doc(this.$props.id)
        }
        
}
```

さらに、これを表示するためのコードをtemplate構文の中に書きましょう。
こちらは、単純に `v-html` 構文で divタグの中に書くだけで十分です。
最終的にリストにするので、<li>の中に書くようにしてください。

```javascript

<template>
    <li class="item">
        <div class="user-box">
            <div v-html="twit.content"></div>
        </div>
    </li>
</template>

```

これで、子コンポーネントの準備は完了です。
明日は親コンポーネントのコードを作成します。