データ取得

ルートが有効化された時にサーバーからデータを取得する必要がしばしばあります。例えば、ユーザープロフィールをレンダリングする前に、サーバーからユーザーデータを取得する必要があります。これを実現するためには 2 種類の方法があります。

  • ナビゲーション後の取得: ナビゲーションを先に実行し、その後次に入ってくるコンポーネントのライフサイクルフック内でデータを取得します。データ取得中にローディングを表示します。

  • ナビゲーション前の取得: ルートに入るガード内でナビゲーション前にデータ取得をします。そして、データ取得後にナビゲーションを実行します。

技術的にはどちらも正当な選択肢です。究極的にはあなたが目指しているユーザーエクスペリエンスに依存します。

ナビゲーション後の取得

このアプローチを取る時は次に来るコンポーネントが即座にナビゲーションされ、レンダリングされます。そして、コンポーネントの created フックの中でデータを取得します。この方法ではネットワーク越しにデータを取得している間にローディング状態を表示する機会があります。また、各 view に対して、異なるローディングの対応をすることもできます。

$route.params.id を元にポストのデータを取得する必要がある Post コンポーネントを想定してみましょう。

<template>
  <div class="post">
    <div class="loading" v-if="loading">
      Loading...
    </div>

    <div v-if="error" class="error">

    </div>

    <div v-if="post" class="content">
      <h2></h2>
      <p></p>
    </div>
  </div>
</template>
export default {
  data () {
    return {
      loading: false,
      post: null,
      error: null
    }
  },
  created () {
    // view が作られた時にデータを取得し、
    // そのデータは既に監視されています
    this.fetchData()
  },
  watch: {
    // ルートが変更されたらこのメソッドを再び呼び出します
    '$route': 'fetchData'
  },
  methods: {
    fetchData () {
      this.error = this.post = null
      this.loading = true
      // getPost をあなたのデータ取得用 util や API ラッパーに置き換えてください
      getPost(this.$route.params.id, (err, post) => {
        this.loading = false
        if (err) {
          this.error = err.toString()
        } else {
          this.post = post
        }
      })
    }
  }
}

ナビゲーション前の取得

こちらのアプローチでは新しいルートへ実際にナビゲーションする前にデータを取得します。次に入ってくるコンポーネント内の beforeRouteEnter ガードでデータ取得を実行できます。データ取得が完了したら next を呼ぶだけです。

export default {
  data () {
    return {
      post: null,
      error: null
    }
  },
  beforeRouteEnter (route, redirect, next) {
    getPost(route.params.id, (err, post) => {
      if (err) {
        // 何らかのグローバルエラーメッセージを表示する
      } else {
        next(vm => {
          vm.post = post
        })
      }
    })
  },
  // コンポーネントが既にレンダリングされている際のルート変更時は
  // ロジックが少し異なります
  watch: {
    $route () {
      this.post = null
      getPost(this.$route.params.id, (err, post) => {
        if (err) {
          this.error = err.toString()
        } else {
          this.post = post
        }
      })
    }
  }
}

次に入ってくる view へのリソースを取得している間、ユーザーは現在の view に滞在します。したがって、データ取得中にプログレスバーや何らかの指標を表示することをオススメします。また、もしデータ取得が失敗した場合、何かグローバルな警告メッセージのようなものを表示する必要があります。

results matching ""

    No results matching ""