#この記事の概要
↓以前書いた記事で作った掲示板アプリの追加実装を行います。
Nuxt.js、Firebase、axiosでパパッと掲示板!
※※※
前回からの続きになっております
以下、適宜axiosメソッドに渡しているURLのYOUR_PROJECT_ID
を自分のプロジェクトIDに置き換える必要があることに注意してください。
YOUR_PROJECT_ID
のままだと以下のエラーが出ます。
追加するのは
・投稿日時の表示
・投稿日時順にソート
目標物
追加で導入するもの
・moment (時刻フォーマットの整形用)
・lodash (ソート用)
moment
$ npm install --save moment
<script>
import moment from 'moment';
#lodash
導入方法は以下参照ください。
webpack プラグインを追加するには?
import webpack from 'webpack'
export default {
//・・・・・・省略
// Build Configuration (https://go.nuxtjs.dev/config-build)
build: {
plugins: [
new webpack.ProvidePlugin({
_: 'lodash'
})
]
}
}
投稿日時の表示
送るデータにcreated
を追加
<script>
//・・・・・・・・・・・省略
methods: {
submitPosts() {
this.$axios
.$post(
'https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts',
{
fields: {
name: {
stringValue: this.name
},
comment: {
stringValue: this.comment
},
//------------↓ここから--------------
created: {
timestampValue: new Date()
}
//------------↑ここまで--------------
}
}
)
.then(() => {
this.name = '';
this.comment = '';
this.getPosts();
});
//・・・・・・・・・・・省略
</script>
そして表示
<template>
<p>名前:{{post.fields.name.stringValue}}</p>
<br>
<p>コメント:{{post.fields.comment.stringValue}}</p>
<br>
<!-----↓ここから-------------------------------------------------------->
<p>投稿日時:{{post.fields.created.timestampValue}}</p>
<br>
<!-----↑ここまで-------------------------------------------------------->
</div>
</div>
</template>
今こんな感じです。
あまり見慣れないフォーマットなのでわかりやすく整形します。
filter
を使ってフォーマットを整形してあげましょう。
さらにここでmoment
を使用しています。
<script>
//・・・・・・・・・・・省略
getPosts() {
this.$axios.$get(
"https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts"
)
.then(res => {
this.posts = res.documents;
});
}
},
//------------↓ここから--------------
filters: {
dateFilter(date) {
return moment(date).format('YYYY/MM/DD HH:mm:ss');
}
}
//------------↑ここまで--------------
};
</script>
<template>
<!-----省略-------------------------->
<p>投稿日時:{{post.fields.created.timestampValue | dateFilter}}</p>
<!-----省略--------------------------->
</template>
投稿日時でソートさせる
現状はこんな感じです。
これをソートさせて行きます。
lodashの_.orderBy
関数を使います
第一引数にソートしたい配列もしくはオブジェクト。
第二引数に値を渡します。
<script>
//・・・・・・・・・・・省略
getPosts() {
this.$axios.$get(
"https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts"
)
.then(res => {
//-----------------------↓ここ--------------
this.posts = _.orderBy(res.documents, 'fields.created.timestampValue');
});
}
},
filters: {
dateFilter(date) {
return moment(date).format('YYYY/MM/DD HH:mm:ss');
}
}
};
</script>
OKです。
最後に昇順、降順を切り替えられる様にします。
昇順、降順の切り替え
<template>
<div>
<h1>掲示板!</h1>
<br>名前
<div>
<input type="text" v-model="name">
</div>コメント
<div>
<textarea v-model="comment"></textarea>
</div>
<br>
<button @click="submitPosts">投稿する</button>
<br>
<br>
<h2>投稿一覧</h2>
<!-----↓ここから-------------------------------------------------------->
<select v-model="selected" @change="getPosts">
<option>新しい順</option>
<option>古い順</option>
</select>
<!-----↑ここまで-------------------------------------------------------->
<!-----省略-------------------------->
</template>
<script>
import moment from 'moment';
export default {
data() {
return {
name: '',
comment: '',
posts: [],
//--------↓ここ--------------
selected: '新しい順'
};
},
//・・・・・・・・・・・省略
</script>
まずプルダウンを用意します
「新しい順」←→「古い順」と切り替わるごとにselected
にその値が入ります、
selected
のデフォルトの値は「新しい順」としておきます。
さらに切り替わるごとにgetPosts
メソッドを呼びリストレンダリングをします。
<script>
//・・・・・・・・・・・省略
getPosts() {
console.log('getPost')
this.$axios
.$get(
'https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/posts'
)
.then(res => {
switch (this.selected) {
case '新しい順':
this.posts = _.orderBy(res.documents, 'fields.created.timestampValue');
break;
case '古い順':
this.posts = _.orderBy(res.documents, 'fields.created.timestampValue', 'desc');
break;
}
});
}
},
//・・・・・・・・・・・省略
</script>
_.orderBy
の第三引数に'desc'
を渡すことで降順になります。
switch文でselected
の値が「新しい順」なら昇順、「古い順」なら降順とします。
※第三引数に'asc'
を渡すことで昇順を指定することもできます。
完成!
<template>
<div>
<h1>掲示板!</h1>
<br>名前
<div>
<input type="text" v-model="name">
</div>コメント
<div>
<textarea v-model="comment"></textarea>
</div>
<br>
<button @click="submitPosts">投稿する</button>
<br>
<br>
<h2>投稿一覧</h2>
<select v-model="selected" @change="getPosts">
<option>新しい順</option>
<option>古い順</option>
</select>
<br>
<div v-for="post in posts" :key="post.id">
<hr>
<br>
<p>名前:{{post.fields.name.stringValue}}</p>
<br>
<p>コメント:{{post.fields.comment.stringValue}}</p>
<br>
<p>投稿日時:{{post.fields.created.timestampValue | dateFilter}}</p>
<br>
</div>
</div>
</template>
<script>
import moment from 'moment';
export default {
data() {
return {
name: '',
comment: '',
posts: [],
selected: '新しい順'
};
},
created() {
this.getPosts();
},
methods: {
submitPosts() {
this.$axios
.$post(
'https://firestore.googleapis.com/v1/projects/vue-test-df33d/databases/(default)/documents/posts',
{
fields: {
name: {
stringValue: this.name
},
comment: {
stringValue: this.comment
},
created: {
timestampValue: new Date()
}
}
}
)
.then(() => {
this.name = '';
this.comment = '';
this.getPosts();
});
},
getPosts() {
this.$axios
.$get(
'https://firestore.googleapis.com/v1/projects/vue-test-df33d/databases/(default)/documents/posts'
)
.then(res => {
switch (this.selected) {
case '新しい順':
this.posts = _.orderBy(res.documents, 'fields.created.timestampValue');
break;
case '古い順':
this.posts = _.orderBy(res.documents, 'fields.created.timestampValue', 'desc');
break;
}
});
}
},
filters: {
dateFilter(date) {
return moment(date).format('YYYY/MM/DD HH:mm:ss');
}
}
};
</script>
お疲れさまでした!
最終的に記事上部の目標物の様になっていればOKです。