vue.js
Firebase

vue.js+firebase+vuefireで作るチャット

仕様

  • vue.js 2.5.13
  • firebase 2.3.2
  • vuefire 1.4.4
  • rails 5.1.4
  • ruby 2.3.0p0 (2015-12-25 revision 53290)

でチャットアプリを作る。webでサーバの設定とかを気にせずチャットを作りたいなと思い、firebaseを用いることにした。

vuefireについて

https://github.com/vuejs/vuefire

vuefireはvue.jsのdataとfirebaseをバインディングしてくれるもの。

やったこと

vue.jsの導入

npm、webpackerを用いて導入。packフォルダ内にてjavascriptを記入していく。vue.jsは対象のidのものが先に読み込まれていないと発火しないのでbody閉じタグ前にjavascriptを記載する必要がある。

firebaseの導入

<!--firebaseのライブラリ読み込み-->
<script src="https://cdn.firebase.com/js/client/2.3.2/firebase.js"></script>

firebaseのライブラリを読み込み、下記をfirebaseアカウントからコピペしてもってくる

index
<script src="https://www.gstatic.com/firebasejs/4.8.1/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "",
    authDomain: "",
    databaseURL: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: ""
  };
  firebase.initializeApp(config);
</script>

これでfirebaseの導入は終わり。簡単。

vuefireの導入

index.html
<head>
  <!-- Vue -->
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <!-- Firebase -->
  <script src="https://gstatic.com/firebasejs/4.0.0/firebase.js"></script>
  <!-- VueFire -->
  <script src="https://unpkg.com/vuefire/dist/vuefire.js"></script>
</head>
chat.js
var Vue = require('vue')
var firebase = require('firebase')
var VueFire = require('vuefire')

// explicit installation required in module environments
Vue.use(VueFire)

下2行がvuefire関連

コードをつらつらと書く

index.html
<div id="chat">
<ul is="transition-group">
  <li v-for="message in messages" :key="message['.key']">
    {{message.contents}}
  </li>
</ul>

 <form v-on:submit.prevent="addMessage" class="form-inline" >
   <input type="text" id="form_board_id" value="<%= @post.id %>" class="hidden">
   <input type="text" id="form_user_id" value="<%= @current_user.id %>" class="hidden">
   <input type="text" name="" v-model="message.contents" class="col-sm-8 form-control show_form">
   <button type="submit" name="button" class="btn btn-primary col-sm-3">送信</button>
 </form>
</div><!--chat-->
chat.js
import Vue from 'vue/dist/vue.esm';
import App from '../app.vue'
var VueFire = require("vuefire");
var Firebase = require("firebase");
Vue.use(VueFire)

var form_user_id = document.getElementById("form_user_id").value;
console.log(form_user_id);
var form_board_id = document.getElementById("form_board_id").value;
console.log(form_board_id);
var firetalks = firebase.database().ref('talks')
var chat = new Vue({
  el: "#chat",
  data: {
    message: {
      user_id:form_user_id,
      board_id:form_board_id,
      contents:'',
    }
  },
  firebase: {
      messages: firetalks
  },
  methods: {
    addMessage: function(){
      firetalks.push(this.message)
      this.message.user_id = ''
      this.message.board_id = ''
      this.message.contents = ''
      }
    }
})

全体的にやっていること

v-modelでユーザーの記入した情報を渡しているが他の情報も一緒に渡したい場合、vue.jsは初期値を無視するのでもともと入れておいてhiddenで隠して送信ができない。しょうがないのでjavascriptのgetElementByIdで送る。submitボタンを押したらmethodsのaddMessageを発火させ、firebaseに送る。そしてそのfirebaseの中身をvue.jsで描写する。

      this.message.user_id = ''
      this.message.board_id = ''
      this.message.contents = ''

の部分は送った後に空に戻すためのもの。(他の記事を参考にしたんだが最初これなんだ?と思って書いてなかった。。。)

チャット機能をmethodsで定義

  methods: {
    addMessage: function(){
      firetalks.push(this.message)
      this.message.user_id = ''
      this.message.board_id = ''
      this.message.contents = ''
      }
    }

messageにvueのインスタンスが入っているのでそれをpushでfirebaseに送っている。pushはfirebaseのメソッド。

firebaseとのバインディング

chat.js
  firebase: {
      messages: firetalks
  },

このfirebaseというのはvuefireを導入すると使えるものでmessagesプロパティに右側のref以下のfirebaseのjsonを紐付けられる。このfiretalksにtalk以下を紐付けている。

つまりどころ

vue.jsのバージョンがかわりまくっててドキュメント探しが大変だった

vue.jsのドキュメント自体はまあまああるんだけどバージョン変ると全然仕様が違って大変だった。。。バージョンの確認をしよう!

どうやってフォームに入力していない情報をvue.jsに渡すか

vue.jsは初期値を無視するのでよくrailsでやっていたvieに初期値を入れてhiddenで隠して一緒に送るができなくて大分苦労した。対処は下記の記事に。

https://qiita.com/you88/items/2051d48454038b78792d

v-forの仕方

<ul is="transition-group">
  <li v-for="message in messages" :key="message['.key']">
    {{message.contents}}
  </li>
</ul>

messagesがfirebase:で定義したプロパティでこれをmessageというエイリアスで繰り返している。