仕様
- 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について
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アカウントからコピペしてもってくる
<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の導入
<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>
var Vue = require('vue')
var firebase = require('firebase')
var VueFire = require('vuefire')
// explicit installation required in module environments
Vue.use(VueFire)
下2行がvuefire関連
コードをつらつらと書く
<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-->
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とのバインディング
firebase: {
messages: firetalks
},
このfirebaseというのはvuefireを導入すると使えるものでmessagesプロパティに右側のref以下のfirebaseのjsonを紐付けられる。このfiretalksにtalk以下を紐付けている。
つまりどころ
vue.jsのバージョンがかわりまくっててドキュメント探しが大変だった
vue.jsのドキュメント自体はまあまああるんだけどバージョン変ると全然仕様が違って大変だった。。。バージョンの確認をしよう!
どうやってフォームに入力していない情報をvue.jsに渡すか
vue.jsは初期値を無視するのでよくrailsでやっていたvieに初期値を入れてhiddenで隠して一緒に送るができなくて大分苦労した。対処は下記の記事に。
v-forの仕方
<ul is="transition-group">
<li v-for="message in messages" :key="message['.key']">
{{message.contents}}
</li>
</ul>
messagesがfirebase:で定義したプロパティでこれをmessageというエイリアスで繰り返している。