web-dev-qa-db-ja.com

非同期HTTP要求を呼び出す必要があるVueJSライフサイクルフックはどれですか?

ページをレンダリングする前に、サーバーに非同期GETリクエストを送信してデータを取得し、データにプロパティを設定する方法を知りたいのですが。これを行う最良の方法は、DOMがレンダリングされる前に動作する3つのライフサイクルフックVue jsオファーのいずれかでこのリクエストを送信する関数を呼び出すことだと聞きました。 3つはbeforeCreate()created()beforeMount()です。理想的には、このリクエストを呼び出す必要があるのはどれですか?なぜ?

10

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()が実行された後の方法でしか処理されません。


では、あなたの決断を導くものは何ですか?

23
acdcjunior

Vue-routerのドキュメントには、コンポーネントのレンダリングに必要なサーバーからデータを取得するときに使用するパターンに関するアドバイスがあります(リンクについては下を参照)。

GETリクエストを実行する場所を決定するために、彼らは最初に、ルートに移動するかどうかを尋ねますbefore非同期GETリクエストが開始されるかafter

データを取得し、ルートに移動する場合(ナビゲーション)の前に、ドキュメントは、着信コンポーネントのbeforeRouteEnter()ガードで非同期リクエストを実行することを提案します非同期データ要求が満たされたら、next()beforeRouteEnter()を必ず呼び出してください。このパターンを選択した場合、コンポーネントのルート/レンダリングへのナビゲーションはデータがフェッチされるまで発生しないため、何らかのロードインジケーターを表示する必要があります。

ルートにナビゲートする場合は、ナビゲーションを開始してからリクエストを開始します()。ドキュメントでは、created()フックでリクエストを実行し、v-ifは、コンポーネントがロードされていること、エラーが発生したこと、またはデータが到着するとビューを条件付きで表示します。

ドキュメントをチェックアウトすることを強くお勧めします。コード例があり、よく書かれています。 https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-before-navigation

4
Bobby

上記のように、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>
3
agm1984

場合によります。

これは、ユーザーエクスペリエンスの目的によって異なります。ルートをすぐに表示しますが、このルートコンテンツに読み込みスピナーを表示しますか?

または、データが取得されるまで待機してから、ルートを表示しますか? (これは、遅延アプリケーションの錯覚を与える可能性があります)

私が述べた最初の方法を実行したい場合は、コンポーネントの作成されたフックでそれを行うことができます。

https://forum.vuejs.org/t/what-is-the-best-hook-to-call-api-to-load-initialisation-data-for-a-component/15167/2

1
Harry Adel