Nuxt.jsのasyncDataとfetchの使い方とその違いについて
Nuxt.jsのasyncDataとfetchの使い方とその違いについて紹介します。
目次から読む
Nuxt.jsのasyncDataとfetchとは
Nuxt.jsでサーバーサードレンダリングを利用する際に使うのが、asyncDataとfetchです。 createdなどではサーバーサイドではなく、クライアントサイドでのレンダリングになります。 クライアントサイドでのレンダリングではソースコードが中身がない状態になってしまうので、SEO的によくありません。 コンポーネントのデータをセットするまえに、サーバーサイドでレンダリングできるようにするために、asyncData()メソッドを使います。asyncData() {
return {}
},data()との違い
data()メソッドととてもよく似ていて、オブジェクトをリターンします。 data()メソッドとの違いは、asyncData()メソッドもfetch()メソッドも、pageコンポーネントが初期化される前に呼び出されるという点です。 そのため、SSR(サーバーサイドレンダリング)が必要なときに使われます。 asyncData()メソッドもfetch()メソッドも、バックエンドで処理されるデータや、setTimeoutのような非同期の処理をコンポーネントがロードされるたびに呼び出されます。 なお、data()メソッドを一緒に使うと、asyncData()のデータが上書きされてしまうので、一緒には使いません。thisキーワードは使えない
asyncData()メソッド内ではthisキーワードはundefinedになり、思うように使えません。 なぜなら、asyncData()はVueコンポーネントが作られる前、つまりthisキーワードが作られる前に実行されるからです。 また、asyncの処理が終わったことをつげないと終了したページを返してエラーが出ます。 その代わり、第一引数にcontextオブジェクトを取り、そのcontextオブジェクト内に必要なパラメータがあり、あらゆる処理が可能になります。Nuxt.jsのasyncDataとfetchの違い
asyncDataは、pageコンポーネントへデータを直接セットする際に使います。apiを叩いてデータを取得する場合に使います。 fetchは、Vuexのstoreからデータをセットする際に使います。asyncData()の使い方
<template>
<div class="posts-page">
<PostList :posts="loadedPosts"/>
</div>
</template><script>
export default {
components: {
PostList,
},
asyncData(context) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
loadedPosts: [
{
id: "1",
title: "最初の投稿",
previewText: "プレビューのテキスト",
thumbnail:"サムネ"
},
{
id: "2",
title: "二回目の投稿",
previewText: "二回目のプレビューテキスト",
thumbnail:"サムネ"
}
]
});
}, 1000);
// reject(new Error())
})
.then(data => {
return data
})
.catch(e => {
context.error(e);
});
}
}</script>fetch()の使い方
上とほとんど同じですが、データはstoreフォルダから取得してきます。<script>
export default {
components: {
PostList,
},
// asyncData(context) {
fetch(context) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
loadedPosts: [
{
id: "1",
title: "最初の投稿",
previewText: "プレビューのテキスト",
thumbnail:"サムネ"
},
{
id: "2",
title: "二回目の投稿",
previewText: "二回目のプレビューテキスト",
thumbnail:"サムネ"
}
]
});
}, 1000);
// reject(new Error())
})
.then(data => {
// return data
context.store.commit('setPosts', data.loadedPosts)
})
.catch(e => {
context.error(e);
});
},
computed: {
loadedPosts() {
return this.$store.getters.loadedPosts
}
}
}
</script>
asyncDataの部分をfetchに変更した点と、then()メソッドの中ではdataではなく、storeから取得する必要があるので、commitを使います。
また、templateタグとの連携があるので、computedを使ってstoreのgettersを使う必要があります。