【Vue × Firebase】各ルームにページ遷移する機能を実装する


#各ルームにページ遷移する機能を実装する

こちらの記事「[認証付きの簡易チャットを作ってみた](https://qiita.com/TMTN/items/2a9527756910e355f132)」でチャットルームの実装は完成してます。

ルールは下記のように変更してます。

```javascript
{
  "rules": {
    // デフォルトの読み書きはすべて拒否
    ".read": "auth != null", // 読み込みは認証が必要
    ".write":"auth != null" // 書き込みは認証が必要
  }
}
```

投稿してルームを作成した後、「ルームに参加」ボタンを押したらそれぞれの各ルームにページ遷移させます。

```html:list.vue
<template>
    <div class="card">
      <div class="face face1 flex">
        <div class="content">
          <img
            class="profile-icon" width="50" height="50" src="../assets/アイコン.jpg"/>
          <h3>{{ list.title }}</h3>
        </div>
      </div>
      <div class="face face2 flex">
        <div class="content flex">
          <p>{{ list.description }}</p>
          <router-link :to="`chat/${list.id}`" class="join-btn flex" >ルームへ参加</router-link>
          <p class="post-time">{{ list.time.toDate().toLocaleString() }}</p>
        </div>
      </div>
    </div>
</template>
```
こちらでは見た目を作成し、「ルームへ参加」ボタンを用意しました。

```javascript:post.vue
 postItem() {
      const id = firebase
        .firestore()
        .collection("posts")
        .doc().id;
      //変数「id」に入れて、コレクションの"posts"を参照して、「id」を取得
      firebase
        .firestore()
        .collection("posts")
        .add({
          title: this.title,
          description: this.description,
          genre: this.genre,
          time: firebase.firestore.FieldValue.serverTimestamp(),
          //サーバ側で値設定
          id: id,
        });
```

投稿に対して各ルームを作成する為に投稿の時点で、それぞれの投稿にIDを持たせて
そのIDを使って各ルームへページ遷移させるように作成しております。

```javascript:post.vue
const id = firebase
        .firestore()
        .collection("posts")
        .doc().id;
```

「id」という変数を用意して、コレクションの"posts"を参照して、「doc().id」でIDを取得します。

```javascript:post.vue
 firebase
        .firestore()
        .collection("posts")
        .add({
          title: this.title,
          description: this.description,
          genre: this.genre,
          time: firebase.firestore.FieldValue.serverTimestamp(),
          //サーバ側で値設定
          id: id, //変数を使用せず「firebase.firestore().collection("posts").doc().id;」でもOK!
        });
```

上記で作成した変数を使って、データを追加する際に、投稿に対してIDをFirestoreに追加することができます。

```javascript:router/index.js
Vue.use(VueRouter);

const routes = [
 
  {
    path: "/chat/:id",
    ///「:id」とすることで、Firestoreで取得した「id」先へページ遷移できる。
    name: "Chat",
    component: Chat,
    meta: { requiresAuth: true },
  },
];
```
vue routerでチャットルームへページ遷移する際に、パスを「/chat」の後ろに「/:id」と
投稿されたIDを元に各ルームにページ遷移させるようにします。

◆参考：[動的ルートマッチング](https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html)


```html:list.vue
<router-link :to="`chat/${list.id}`" class="join-btn flex" >ルームへ参加</router-link>
```

vue routerにて「/chat/:id」と指定してあげたので、ページ遷移させる際にURLをIDによって動的に変化させる必要があります。
そんなときにrouter-linkを使います。

◆参考：[プログラムによるナビゲーション](https://router.vuejs.org/ja/guide/essentials/navigation.html)

```javascript:chat.vue
 created() {
    firebase.auth().onAuthStateChanged(user => {
      // ログイン状態ならuserが取得できる
      this.user = user ? user : {};
      const ref_message = firebase.database().ref(this.$route.params.id);
　     //(this.$route.params.id)でvue routerにて指定したルートにマッチさせる。
      if (user) {
        this.chat = [];
        // limitToLast(10)で並べ替えられた「message」の最後の10個を取得。
        // on()は、message に変更があったときのハンドラを登録
        //child_addedは、データベースのリスト「message」を取得。
        ref_message.limitToLast(10).on("child_added", this.childAdded);
      } else {
        // message に変更があったときのハンドラを解除
        ref_message.limitToLast(10).off("child_added", this.childAdded);
      }
    });
  },
```

◆参考：[動的ルートマッチング](https://router.vuejs.org/ja/guide/essentials/dynamic-matching.html)

これで各ルームにページ遷移する機能を実装することが出来ました。