Vue.jsとFirebaseでリアルタイムチャットアプリを実装した
フロントエンドのフレームワークについてキャッチアップするために、こちらの本を読みました。
React、Angular、Vue.js、React Nativeを使って学ぶ はじめてのフロントエンド開発
- 作者: 原一浩,taisa,小松大輔,永井孝,池内孝啓,新井正貴,橋本安司,日野洋一郎
- 出版社/メーカー: 技術評論社
- 発売日: 2018/05/09
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
どんな本か?
本書では、フロントエンドの最新動向(特にフレームワークについて)をサンプルアプリケーションを開発しながら学べるようになっています。
JavaScriptのフロントエンドフレームワークが今のように複雑かつ大規模になっていった背景について歴史的経緯含めてわかりやすく解説してあるため、フロントエンドについての全体像を整理しつつキャッチアップしたい人にとてもおすすめな内容になっています。
Firebaseも触れる
サンプルアプリケーションではバックエンドAPIをFirebaseで割と手軽に構築できるようになっています。
Vue.jsとFirebaseで作るリアルタイムチャットアプリケーション
概要
Slackっぽいチャットアプリケーションを作ります。
本書ではVue, React, Angularそれぞれのフレームワークで全く同じサンプルコードが用意されていますが、今回はVueで実装してみました。
npmでvueをインストールするところから始まり、VueCLIによる環境構築、単一ファイルコンポーネントの作成、Vuexによる状態管理とVueの基本的な機能をさらいながら実装を進める手順となっています。
プロジェクトの作成
Vueをインストールし、プロジェクトを作成します。
$ npm i vue ... $ vue init webpack vueChat ? Project name(vueChat) vueChat ? Project description(A Vue.js project) A sample chat of Vue.js ? Author ? Vue build (Use arrow keys) > Runtime + Compiler: recommended for most users ? Install vue-router? (Y/n) Y ? Install vue-router? (Y/n) Y ? Use ESLint to lint your code? (Y/n) n ? Set up unit tests (Y/n) n ? SetUp e2e tests with Nightwatch? (Y/n) n > Yes, use NPM Installing project depeneencies … $ cd vueChat $ npm run dev
これで http://localhost:8080
にブラウザでアクセスできるようになります。
プロジェクトのディレクトリ構成
main.jsがアプリケーションの起点でありエントリポイントとなります。
vueChat ├── build ├── config ├── index.html ├── node_modules ├── package-lock.json ├── package.json ├── src │ └── App.vue │ └── assets │ └── components │ └── Chat │ └── chat.css │ └── chat.js │ └── chat.pug │ └── index.vue │ └── main.js │ └── router ├── static
単一ファイルコンポーネント
単一のファイルにテンプレート、スタイル、ロジックをまとめることで保守性を担保します。今回はそれぞれのブロックごとにファイルを切り出し、index.vueでまとめています。
index.vue
<template lang="pug" src="./chat.pug" /> <script src="./chat.js" /> <style scoped src="./chat.css" />
chat.js
import { mapGetters, mapActions } from 'vuex' import { GET_CHANNELS, // SET_MESSAGE } from '../../store/mutation-types' import MessageList from '../MessageList' export default { name: 'chat', mounted(){ this.GET_CHANNELS() this.GET_MESSAGES(this.$route.params.cname) }, components: { 'message-list': MessageList }, computed: { ...mapGetters([ 'messages', 'channels' ]), }, beforeRouteUpdate(to, from, next) { this.GET_MESSAGES(to.params.cname) next() }, methods: { ...mapActions([ // SET_MESSAGE, GET_CHANNELS, "GET_MESSAGES", "POST_MESSAGES" ]), send_message(){ // this.SET_MESSAGE(this.message) this.POST_MESSAGES({"cname": this.$route.params.cname, "message": this.message}) this.message = "" } }, data() { return { message: "" } } }
chat.pug
el-container el-aside ul li(v-for="(channel) in channels") router-link(:to="{name: 'channel', params: { cname: channel }}") {{ channel }} el-container el-header {{ $route.params.cname }} el-main message-list(:messages='messages') el-footer el-input(type="text" v-model="message") el-button("@click"="send_message") SEND
chat.css
ul { list-style-type: none; padding: 0; } .el-header { border-bottom:1px solid black; } .el-header, .el-footer { background-color: #ffffff; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #4a3a4a; text-align: center; width: 100px!important; } .el-aside a { color: #ffffff; text-decoration:none; font-weight: bold; } .el-main { background-color: #ffffff; color: #333; text-align: center; } .el-container{ height: 100vh; } .el-input { width: 50%; }
誤植に注意
注意点としては誤植により思うように動かない箇所が何箇所かありましたが注意深く読み直せば自力で解消できるレベルのものでした。
公式の正誤表が用意されているようなので、ハマったらチェックしてみるといいかもしれません。
誤植訂正情報 · okachijs/jsframeworkbook Wiki · GitHub
まとめ
同じアプリケーションを複数のフレームワークで実装したときのどのような違いが生じるかという比較ができてとても参考になりました。