前回の投稿、 Vue を使用したより高度なルーティングでは、TransitionsVueRouterの使用について説明しました。 今回は、データフェッチVueルーターについて説明します。

データフェッチを使用すると、ルーティングされたコンポーネントに非同期データをロードできます。 コンポーネントがロードされる前または後にデータをフェッチするかどうかを指定することもできます。 これらの戦略はどちらも同じように実行可能ですが、実装が異なります。 両方をカバーします。

Vueプロジェクトのセットアップ

これは高度なVueルーターテクニックに関するさらに別の投稿であるため、基本的なセットアップに既に精通していることを前提としています。 ただし、残りの投稿で使用する開始点を定義しましょう。

# Yarn
$ yarn add vue-router

# npm
$ npm install vue-router --save
main.js
import Vue from 'vue';
import VueRouter from 'vue-router';

import App from './App';
import Swamp from './components/Swamp';
import Gator from './components/Gator';

Vue.use(VueRouter);

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp },
    { path: '/gator', component: Gator }
  ]
});

new Vue({
  render: h => h(App),
  router
}).$mount('#app')
App.vue
<template>
  <div id="app">
    <div class="nav">
      <router-link to="/swamp">Swamp</router-link> |
      <router-link to="/gator">Gator</router-link>
    </div>
    <hr />
    <div class="router-view">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default { name: 'App' }
</script>
components / Swamp.vue
<template>
  <div>Welcome to the Swamp, {{ name }}!</div>
</template>

<script>
export default {
  name: 'Swamp',
  data() {
    return { name: null }
  },
}
</script>
components / Gator.vue
<template>
  <div>Howdy, Gator {{ name }}!</div>
</template>

<script>
export default {
  name: 'Gator',
  data() {
    return { name: null }
  }
}
</script>

データフェッチ

単純なHTTPをモックする関数があったとしましょう GET と呼ばれる pretendGet():

scripts / pretendGet.js
export default (callback) => {
  setTimeout(() => {
    callback(null, 'Alice');
  }, 500);
}

500ms後 pretendGet() 文字列を返します 'Alice' コールバックメソッドへ callback. 次の例では、これを使用してサーバーリクエストをモックします。

ナビゲーション前のフェッチ

before ナビゲーションを取得すると、ルーティングされたコンポーネントに、ユーザーに表示される前に必要なデータが含まれていることを確認できます。 このアプローチでは、 beforeRouteEnter Vue Router が、ユーザーがこのコンポーネントへの移動を要求したときに、それがロードされる前に呼び出すメソッド。 また、 beforeRouteUpdate ルートが変更されたときに呼び出されるメソッド。 これは、経由でアクセスできるルートパラメータに関連するデータをフェッチする場合に便利です。 to.params.

components / Gator.vue
import pretendGet from '../scripts/pretendGet';

export default {
  name: 'Gator',
  data() {
    return { name: null }
  },
  // Component not loaded yet
  beforeRouteEnter(to, from, next) {
    pretendGet((err, name) => {
      next(vm => vm.setName(err, name));
    });
  },
  // Component already loaded and route changes
  beforeRouteUpdate(to, from, next) {
    this.name = null;
    pretendGet((err, name) => {
      this.setName(err, name);
      next();
    });
  },
  methods: {
    setName(err, name) {
      if (err) {
        console.error(err);
      } else {
        this.name = name;
      }
    }
  }
}

データがフェッチされるまでナビゲーションは行われないことに注意してください。 このため、データがフェッチされていることを示す何らかのプログレスバーまたはインジケーターを表示することをお勧めします。 エラーがある場合は、それも表示することをお勧めします。

ナビゲーション後のフェッチ

afterナビゲーションをフェッチすることも有効なアプローチです。 この場合、 created() ライフサイクルフックデータフェッチメソッドを呼び出す fetchName(). また、 watch 上のプロパティ $route だから私たちは呼び出すことができます fetchName() ルートが変わるたびに。

components / Swamp.vue
import pretendGet from '../scripts/pretendGet';

export default {
  name: 'Swamp',
  data() {
    return { name: null }
  },
  created() {
    this.fetchName();
  },
  watch: {
    // Re-fetch when route changes
    '$route': 'fetchName'
  },
  methods: {
    fetchName() {
      pretendGet((err, name) => {
        if (err) {
          console.error(err);
        } else {
          this.name = name;
        }
      });
    }
  }
}

このアプローチでは、コンポーネントが最初にレンダリングされたときにデータの準備ができていないことを考慮する必要があることに注意してください。 プレースホルダーまたはスケルトンプレースホルダーをインジケーターと一緒に含めて、発生する可能性のあるエラーとともにデータがフェッチされていることをユーザーに通知することをお勧めします。

まとめ

Vue Router Data Fetching は、外部ソースからのデータのフェッチに依存するコンポーネントのスムーズなユーザーエクスペリエンスを保証するための優れた方法です。 アプリ全体の通知や進行状況インジケーターを使用するのが好きな場合は、ナビゲーションの前にフェッチすることをお勧めします。 この種のものをコンポーネントレベルで処理したい場合は、ナビゲーション後にフェッチするのが適切なアプローチかもしれません。 いつものように、必ずドキュメントを読んでください!