Vueを使用したさらに高度なルーティング:データフェッチ

提供:Dev Guides
移動先:案内検索

前回の投稿、 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>

データフェッチ

pretendGet()と呼ばれる単純なHTTPGETをモックする関数があるとしましょう。

scripts / pretendGet.js

export default (callback) => {
  setTimeout(() => {
    callback(null, 'Alice');
  }, 500);
}

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

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

before ナビゲーションを取得すると、ルーティングされたコンポーネントに、ユーザーに表示される前に必要なデータが含まれていることを確認できます。 このアプローチでは、beforeRouteEnterメソッドを追加しました。このメソッドは、ユーザーがこのコンポーネントへの移動を要求したときに、ロードされる前に VueRouterが呼び出します。 ルートが変更されたときに呼び出される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()を呼び出します。 また、$routewatchプロパティを定義して、ルートが変更されるたびに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ルーター データフェッチ is a great way to ensure a smooth user experience for your components that rely on fetching data from external sources. Fetching before navigation is a good approach if you’re a fan of using app-wide notifications or progress indicators. If you’d rather handle this kind of stuff on a component level then fetching after navigation might be the right approach for you. As always, make sure to ドキュメントを読む!