Vue.js、Firebase、axiosでパパッと掲示板！

# この記事の概要
超簡単な掲示板アプリをパパっと作成します。
細かいことはいいからとりあえずVue.jsで何かアプリを作ってみたいという方にオススメです。

# 目標物

![demo](https://gyazo.com/4277e098e82d0176e3723649acb16871/raw)
***
# 開発環境

・macOS Catalina 10.15.7
・@vue/cli 4.5.6
・npm 6.9.0
・node v10.16.0

# 前提
・node、npm、vue-cli環境が整っている。
・firebaseのアカウントを作成している。
***

# firebaseのプロジェクト作成。
[firebase](https://firebase.google.com/?gclid=Cj0KCQiAqdP9BRDVARIsAGSZ8Al9ifR9EwAx4up5ikW0LE6fsiemc964Gh_UaU3n1jqC-GvF_xvwOJIaAgddEALw_wcB)に行き
【コンソールへ移動】
→【プロジェクトの作成】または【プロジェクトの追加】

プロジェクト名は「vue-test」としておきます。

![スクリーンショット 2020-11-18 11.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/9075d757-613e-982d-3e77-bc305a176f77.png)
***

アナリティクスは無効でOKです。

![スクリーンショット 2020-11-19 12.04.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/9405cfa0-23d7-2530-3e1c-4e37eb3b8b90.png)
***

プロジェクトができました。
![スクリーンショット 2020-11-18 11.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/2a2bab8d-e1be-3c1a-3a62-500a0559437a.png)
***
こんなページに来たらOKです。
![スクリーンショット 2020-11-18 11.43.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/2f888145-f525-3a3c-57a3-8cc693127edc.png)
# DBの作成
Cloud Firestoreを使用します。
![スクリーンショット 2020-11-18 11.45.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/1a093f52-5cbf-e589-4395-640710f467d7.png)
***
テストモードでOKです。
![スクリーンショット 2020-11-18 11.45.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/e01cf271-ebc1-5611-815f-7ffc1d28b870.png)
***
ロケーションを「asia-norheast1(東京)」に設定。
![スクリーンショット 2020-11-18 11.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/7c4b8500-5865-08e8-1ea8-cdc73366f9ad.png)
***
DBができました。
これでfirebaseの設定は終わりです！
![スクリーンショット 2020-11-18 11.47.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/116e6c63-2748-7b28-cf44-00e1f84c9584.png)

***
# プロジェクト作成

```:ターミナル
$ vue create vue-test
$ cd vue-testcd
vue-test$

```
axiosをインストール

```:ターミナル
vue-test$　npm install axios
```

![スクリーンショット 2020-11-18 12.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/7e3aba54-7808-73dd-4e8e-319c45e279bb.png)
***
アプリ立ち上げ。

```:ターミナル
vue-test$　npm run serve   
```
![スクリーンショット 2020-11-19 12.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/a7dd6b66-1499-ff93-439b-45ab83651090.png)

# View作成
```vuejs:App.vue
<template>
  <div>
    <h1>掲示板！</h1>
    名前
    <div><input type="text" v-model="name"></div>
    コメント
    <div><textarea v-model="comment"></textarea></div>
    <br>
    <button @click="submitPosts">投稿する</button>
    <br><br>
    <h2>投稿一覧</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: '',
      comment: ''
    }
  },
  methods: {
    submitPosts() {
      console.log('submit');
    }
  }
}
</script>

```
***
とりあえず【投稿】ボタンを押したら【submit】と出力させておきましょう。
![スクリーンショット 2020-11-18 12.06.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/ee357a7c-90de-2e67-856f-2808b5aefca0.png)
***

# データを送る
まずaxiosを`import`する必要があります。

```vuejs:App.vue
<script>
import axios from 'axios'//         <-
export default {
  data() {
    return {
      name: '',
      comment: ''
    }
  },
</script>

```

データを送る為に`axios.post()`を使用します。
第一引数：**サーバーのURL**
第二引数：**データの内容**
第三引数：**オプション**（任意）

```vuejs:App.vue
<script>
import axios from 'axios'
export default {
  data() {
    return {
      name: '',
      comment: ''
    }
  },
  methods: {
    submitPosts() {
//----↓ここから--------------
      axios.post(
        "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts",
        {
          fields: {
            name: {
              stringValue: this.name
            },
            comment: {
              stringValue: this.comment
            }
          }
        }
      ).then(() => {
        this.name = '';
        this.comment = '';
      });
//---↑ここまで--------------
    }
  }
}
</script>

```
今回オプションは取りません。

`.then`には通信が成功したときの処理を指定できます。
今回は`this.name`と`this.comment`を空にしています。

URLは
`https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/cities/LA`
↑を入れます。
[こちら](https://firebase.google.com/docs/firestore/use-rest-api?hl=ja)に乗ってあるのを持って来ただけです。

**※****※****※**
しかしこれでは不十分で、URL内の`YOUR_PROJECT_ID`の部分を自分の**プロジェクトID**に置き換える必要があります。

プロジェクトIDはここに記載されています
![スクリーンショット 2020-11-19 13.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/d5eda0a9-49fc-f265-0bf4-1c75ab269ed8.png)
↓
![スクリーンショット 2020-11-19 13.36.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/d64c44bb-7c80-bafb-1c25-3290226825c1.png)
***
  
**以下、適宜`YOUR_PROJECT_ID`を自分のプロジェクトIDに置き換える必要があることに注意してください。** 
`YOUR_PROJECT_ID`のままだと以下のエラーが出ます。
![スクリーンショット 2020-11-24 20.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/dcdbd945-b0da-8c99-4eab-80c0be24e4c6.png)
***

次に、URL末尾の`cities/LA`を任意のコレクション名（データを格納する場所の名前）にします。
今回は`posts`とします。

URLの変更ができたらデータを送ってみましょう。
![スクリーンショット 2020-11-19 14.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/9f0d8b6f-e745-7081-4056-e6976989089b.png)

![スクリーンショット 2020-11-19 14.15.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/cf2b518c-cff1-0903-11d0-519f84ab6b84.png)
***
データが入っています！

# データの取得
では今度はサーバーからデータを取ってきましょう。
データの取得は`axios.get()`を使用します。
第一引数：**サーバーのURL**
第二引数：**オプション**（任意）

サーバーのURLは`axios.post()`で使用したものと全く同じです。

取得するタイミングは**ロード時**と**データ送信時**に行いたいので、
`getPosts`メソッドを作り各所で呼び出しましょう。

```vuejs:App.vue
<script>
import axios from "axios";
export default {
  data() {
    return {
      name: '',
      comment: ''
    };
  },
//----↓ここから--------------
  created() {
    this.getPosts();
  },
//----↑ここまで--------------
  methods: {
    submitPosts() {
      axios.post(
        "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts",
        {
          fields: {
            name: {
              stringValue: this.name
            },
            comment: {
              stringValue: this.comment
            }
          }
        }
      )
      .then(() => {
        this.name = '';
        this.comment = '';
//----↓ここ--------------
        this.getPosts();
      });
    },
//----↓ここから--------------
    getPosts() {
      axios.get(
        "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts"
      )
      .then(res => {
        console.log(res.data.documents);
      });
    }
//----↑ここまで--------------
  }
};
</script>

```

`.then(res => {
            console.log(res.data.documents);
      });`
この`res`の中に取得したデータが入っているので確認してみます。
![スクリーンショット 2020-11-19 14.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/d36aefab-660d-8155-582e-e510197603ab.png)

バッチリ入っています。
あとはこの配列を`v-for`で順番に表示させていきます。

# データの表示

・`date`に空配列`posts`を準備。
・`getPosts`が呼ばれたタイミングで`res.data.documents`を配列`posts`に格納。
・配列`posts`をリストレンダリングしています。
 

```vuejs:App.vue
<template>
  <div>
    <h1>掲示板！</h1>名前
    <div>
      <input type="text" v-model="name">
    </div>コメント
    <div>
      <textarea v-model="comment"></textarea>
    </div>
    <br>
    <button @click="submitPosts">投稿する</button>
    <br>
    <br>
    <h2>投稿一覧</h2>
<!-----↓ここから-------------------------------------------------------->
    <div v-for="post in posts" :key="post.name">
      <hr>
      <p>名前：{{post.fields.name.stringValue}}</p>
      <p>コメント：{{post.fields.comment.stringValue}}</p>
    </div>
<!-----↑ここまで-------------------------------------------------------->
  </div>
</template>

<script>
import axios from "axios";
export default {
  data() {
    return {
      name: '',
      comment: '',
//----↓ここ--------------------------
      posts: ''
    };
  },
  created() {
    this.getPosts();
  },
  methods: {
    submitPosts() {
      axios.post(
        "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts",
        {
          fields: {
            name: {
              stringValue: this.name
            },
            comment: {
              stringValue: this.comment
            }
          }
        }
      ).then(() => {
        this.name = '';
        this.comment = '';
        this.getPosts();
      });
    },
    getPosts() {
      axios.get(
        "https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts"
      )
      .then(res => {
//----↓ここ--------------------------
        this.posts = res.data.documents;
      });
    }
  }
};
</script>

```

# 完成！
![スクリーンショット 2020-11-19 14.55.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635852/c02bd3d8-f713-9dcb-ee0d-376840f3e148.png)
***
ここまで見て頂きありがとうございました！

とりあえず作って動かすを目的にしているので細かい解説はしていません（←できません）

コピペで動かす際はURLの`YOUR_PROJECT_ID`を適宜自身のプロジェクトIDに置き換えることを注意してください。