ページをレンダリングする前に、サーバーに非同期GETリクエストを送信してデータを取得し、データにプロパティを設定する方法を知りたいのですが。これを行う最良の方法は、DOMがレンダリングされる前に動作する3つのライフサイクルフックVue jsオファーのいずれかでこのリクエストを送信する関数を呼び出すことだと聞きました。 3つはbeforeCreate()
、created()
、beforeMount()
です。理想的には、このリクエストを呼び出す必要があるのはどれですか?なぜ?
Vueの初期化コードは同期的に実行されます。
技術的には、これらのフックで実行する非同期コードは、すべてのフックが終了した後にのみ応答します。デモを見る:
new Vue({
el: '#app',
beforeCreate() {
setTimeout(() => { console.log('fastest asynchronous code ever') }, 0);
console.log('beforeCreate hook done');
},
created() {
console.log('created hook done');
},
beforeMount() {
console.log('beforeMount hook done');
},
mounted() {
console.log('mounted hook done');
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
Check the console.
</div>
言い換えれば、beforeCreate
でAjax呼び出しを行うと、APIがどれほど速く応答しても、応答はcreated()
が実行された後の方法でしか処理されません。
では、あなたの決断を導くものは何ですか?
beforeCreate()
を使用data
の読み取りまたは変更が必要ですか?created()
を使用beforeCreate()
とcreated()
の間でのみ初期化されるため、 created()
の前にデータを割り当てると、失われます 。created()
?の後に生成されるものが必要です。beforeMount()
を使用created()
で利用できないもの、およびbeforeMount()
で利用できるものは何も知りません )コンパイルされたthis.$options.render
レンダリング関数以外 ( ソースも を参照)、このケースは本当にまれな状況であるに違いありません。Vue-routerのドキュメントには、コンポーネントのレンダリングに必要なサーバーからデータを取得するときに使用するパターンに関するアドバイスがあります(リンクについては下を参照)。
GETリクエストを実行する場所を決定するために、彼らは最初に、ルートに移動するかどうかを尋ねますbefore非同期GETリクエストが開始されるかafter
データを取得し、ルートに移動する場合(ナビゲーション)の前に、ドキュメントは、着信コンポーネントのbeforeRouteEnter()
ガードで非同期リクエストを実行することを提案します非同期データ要求が満たされたら、next()
でbeforeRouteEnter()
を必ず呼び出してください。このパターンを選択した場合、コンポーネントのルート/レンダリングへのナビゲーションはデータがフェッチされるまで発生しないため、何らかのロードインジケーターを表示する必要があります。
ルートにナビゲートする場合は、ナビゲーションを開始してからリクエストを開始します()。ドキュメントでは、created()
フックでリクエストを実行し、v-if
は、コンポーネントがロードされていること、エラーが発生したこと、またはデータが到着するとビューを条件付きで表示します。
ドキュメントをチェックアウトすることを強くお勧めします。コード例があり、よく書かれています。 https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-before-navigation
上記のように、VueとReact=の両方に存在する重要な問題は、コンポーネントが作成される前にネットワーク要求を行い、データが到着した場合、データを設定するインスタンスはありません。
beforeCreated
は、ReactのcomponentWillMount
に似ています。コンポーネントが存在する前にデータを取り戻す可能性があるため、通常はここでネットワークリクエストを実行したくないでしょう。 this.data = data
を設定するようなものですが、コンポーネントがないため、this
はまだ存在しません。
Reactのより良い場所はcomponentDidMount
ですが、気にしません。Vueでは、コンポーネントが作成されているのでcreated
がより良い場所です既に、this
が存在します。
以下に例を示します。
<template>
<div>
<span v-if="error">{{ error }}</span><br>
I like:<br>
{{ data }}
</div>
</template>
<script>
export default {
data() {
return {
data: '',
error: undefined,
}
},
async created() {
try {
const response = await axios.get('/endpoint/stuff')
this.data = response
} catch (err) {
this.error = err
}
},
}
</script>
場合によります。
これは、ユーザーエクスペリエンスの目的によって異なります。ルートをすぐに表示しますが、このルートコンテンツに読み込みスピナーを表示しますか?
または、データが取得されるまで待機してから、ルートを表示しますか? (これは、遅延アプリケーションの錯覚を与える可能性があります)
私が述べた最初の方法を実行したい場合は、コンポーネントの作成されたフックでそれを行うことができます。