FirebaseとNuxt.jsで掲示板を作りました。削除ボタンが機能しなかったり未完成の部分があります。
この記事は
- Firebaseを活用してみたい
- Nuxt.jsでアプリ作ってみたい
という人向けに書いてみました。
**「こんな感じでやれば短時間でFirebaseと連携できます」**的なものを記事にしました。作っていく際に参考にした記事と躓いた点も書いていきます。中途半端な出来ですが初心者向けに書いてみました!
##Firebaseとは何?
Firebaseはリアルタイムでデータ同期ができるモバイルプラットフォームです。Firebaseを使うとサーバを立てたり、管理や保守がいらなくなるのでフロントサイドの作成に集中できます。
##NuxtJSとは何?
NuxtJSは、Vueファイルで記述できるフレームワークです。モジュール構造で拡張でき一部分から徐々に採用することが可能で、静的なページから複雑なwebアプリケーションまで、あらゆるものの作成に使用できます。
以下公式から抜粋
本質的に汎用性があり、さまざまなターゲット(サーバー、サーバーレス、または静的)をサポートし、サーバーサイドのレンダリングは切り替えることができます。
強力なモジュールエコシステムにより拡張可能で、REST や GraphQL エンドポイント、お気に入りの CMS や CSS フレームワークなどさまざまなものに簡単に接続できます。
NuxtJS は Vue.js プロジェクトのバックボーンであり、柔軟でありながら自信を持ってプロジェクトを構築するための構造を提供します。
#めちゃくちゃ簡易的な掲示板
##できたもの
実際に利用できます!コメントしてみてください!
http://keiziban.tk/about/
簡易的な掲示板を作ってみました!削除ボタンは飾りです。https://t.co/73cLQb3M8d#protoout #JavaScript #Firebase pic.twitter.com/Hu4AITFnL0
— Toshiki (@Hirasawa1987) September 9, 2020
##機能
名前、コメントの投稿がきる
#作成手順
任意のフォルダーに移動してVScode
のTerminalより
yarn
を使って以下のコマンドでNuxtプロジェクトを作成することができます。
yarn create nuxt-app cloudfireTest
を実行すると、UIフレームワークなどの機能が必要か聞かれるので選択していき、終了したら
yarn run dev
で起動させます。無事に終了したら以下のアドレスにアクセスして実行されているか見ます。
http://localhost:3000
続いて
yarn add firebase
でインストールて完了です。
今回にUIフレームワークはBootstrapVueを選択したので、こちらでどのようなスタイルになるのかを調べました。
##フォルダ構造
#pages
pagesディレクトリに.vue
ファイルを作成するとページのルーティングができます、index.vue
が/
になり、about.vue
が/about
でアクセスできます
<template>
<div class="container">
<div class="jumbotron">
<div class="container">
<h1 class="display-3">掲示板</h1>
</div>
<div class="links">
<client-only placeholder="Loading...">
<Memo />
</client-only>
</div>
</div>
</div>
</template>
<script>
import Memo from '~/components/Memo.vue'
export default {
components: {
Memo
}
}
</script>
以下の部分でComponents内に作るMemo.vue
が呼び出されます。
<client-only placeholder="Loading...">
<Memo />
</client-only>
#Components
何度も利用可能な.vue
で構成されています。今回のFirebaseとの連携はこちらに書いていきます。まずはComponents
にMemo.vue
を追加。
<template>
<div>
<p>
<b-form-input v-model="name" placeholder="名前"></b-form-input>
<b-form-textarea input v-model="age" placeholder="コメント" id="button"></b-form-textarea>
<b-button id="button" size="sm" variant="outline-success" v-on:click="post(); removetext()">投稿</b-button>
</p>
<ul v-for="(data, index) in allData" :key="data.id" class="menu-list" >
<li>
名前:{{data.name}} <br>
コメント:{{data.age}}<br>
<b-button size="sm" variant="outline-danger" class="delete" @click="switchDelateAlarm(); getIndex(index)">
削除
</b-button>
</li>
</ul>
<div v-show="showDelateAlarm" id="overlay">
<div id="delateAlarm">
<p>コメントを削除します</p>
<b-button size="sm" variant="outline-dark" v-on:click="closeModal">
戻る
</b-button>
<b-button size="sm" variant="outline-danger" @click="switchDelateAlarm(); deleteItem(data.id)">
削除
</b-button>
</div>
</div>
</div>
</template>
<script>
import firebase from "firebase/app";
import "firebase/firestore";
export default {
components: {},
data(){
return{
db: {},
allData: [],
name: '',
age: '',
showDelateAlarm: false,
id: [],
}
},
methods: {
init: () => {
const config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
firebase.initializeApp(config);
},
post: function(){
const testId = firebase.firestore().collection('memos').doc().id; //ユニークなIDを生成
const docRef = firebase.firestore().collection('memos').doc(testId);
const setAda = docRef.set({
name: this.name,
age: this.age,
createdAt: new Date()
});
this.get();
},
get: function(){
this.allData = [];
firebase.firestore().collection('memos').get().then(snapshot => {
snapshot.forEach(doc => {
this.id = doc.id;
console.log(this.id);
const array = [];
console.log(array);
this.allData.push(doc.data());
})
});
},
getIndex: function() {
console.log(firebase.firestore().collection('memos'));
},
deleteItem: function(deleteId, getIndex) {
const db = firebase.firestore();
db.collection("memos").doc(deleteId).delete().then(function() {
console.log("Document successfully deleted!");
}).catch(function(error) {
console.error("Error removing document: ", error);
});
this.showDelateAlarm = false;
this.get();
},
switchDelateAlarm: function() {
this.showDelateAlarm = true
},
closeModal: function(){
this.showDelateAlarm = false
},
removetext: function() {
this.name = '';
this.age = '';
},
},
mounted(){
this.init();
this.get();
},
}
</script>
<style>
#delateAlarm{
z-index:2;
width:50%;
padding: 1em;
background:#fff;
}
#overlay{
/* 要素を重ねた時の順番 */
z-index:1;
/* 画面全体を覆う設定 */
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
background-color:rgba(0,0,0,0.5);
/* 画面の中央に要素を表示させる設定 */
display: flex;
align-items: center;
justify-content: center;
border-radius: 10%;
}
ul {
display: block;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding: 0px;
list-style: none;
}
#button {
margin-top: 2px;
}
</style>
###Cloud Firestoreの設定
こちらの部分にファイヤーベースの設定→全般の下のほうにあるマイアプリ
からコピー&ペーストします。
const config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
今回はあらかじめCloud Firestoreのコレクションにmemos
作成しておきます。
###設定
以下はpost
の部分を抜粋しています。
post: function(){
const testId = firebase.firestore().collection('memos').doc().id; //ユニークなIDを生成
const docRef = firebase.firestore().collection('memos').doc(testId);
const setAda = docRef.set({
name: this.name,
age: this.age,
createdAt: new Date()
});
this.get();
},
#躓いた部分
削除ボタンの実装に躓きました。ボタンに紐づいたドキュメントidが取得できずボタンは配置されていますが、機能しません。
#参考にした記事
- ざっくりFirestore + Vue.jsの使い方
- 【v2対応】Nuxt.jsとFirebaseを組み合わせて爆速でWebアプリケーションを構築する
- 【Nuxt.js】todoアプリを作成してみた①
- firestore, vue.jsでリアルタイム同期のチャットを実装してみる [チュートリアル形式]
- Vue.js おすすめライブラリ 21選(おまけ+1)
#終わりに
読んでいただきありがとうございました、よくわからん部分もあったと思います。私自身わかっていない部分が多いですが、とにかく一言いってやりたいという方!是非こちらで絡んでやってください。