【Vue.js】Vue Router上でコンポーネントに値を渡す前に非同期処理の完了を待たせる

  • 2020年2月6日
  • 2023年10月23日
  • Vue

 Vue RouterはVue.jsの公式のルーターライブラリです。SPA(シングルページアプリケーション)的にVue.jsでサイトを構築するならまず出番があります。
紹介 | Vue Router
 Vue Routerのルーティングでは次の様にパラメータを遷移先ページコンポーネントに渡します。

const options: RouterOptions = {
    mode: 'history',
    routes: [
        {
            path: '/user/:id',
            name: 'userShow',
            component: Show,
            props: (route)=> {
                return {id: route.params.id};
            },
        },
    ],
};
export default new Router(options);

 例ではpropsで渡しています。
ルートコンポーネントにプロパティを渡す | Vue Router
 Userの情報をAPIで取ってくるとき、IDに該当するユーザがいない場合404が返ってきます。このプロパティを渡す仕組みの途中でAPIを叩くとしたら次の様にできそうです。

const options: RouterOptions = {
    mode: 'history',
    routes: [
        {
            path: '/user/:id',
            name: 'userShow',
            component: Show,
            async props: (route)=> {
                return {user: await UserRepository.find(to.params.id)};
            },
        },
    ],
};
export default new Router(options);

 APIリポジトリから返ってきたユーザインスタンスをそのまま渡します。APIリポジトリで例外が発生した場合、ルーティングはpropsを解決できずに失敗する、と期待します。実際は成功しません。async, awaitによってAPIを叩く処理のPromiseが返る関数をpropsに記述しましたが、props実行時にVue Routerはawaitしてくれずにundefinedをpropsの値としてしまいます。いささかハック的な気もしますが解決方法は次です。

const options: RouterOptions = {
    mode: 'history',
    routes: [
        {
            path: '/user/:id',
            name: 'userShow',
            component: Show,
            beforeEnter: (to, from, next) => {
                UserRepository.find(to.params.id).then((user) => {
                    to.meta.user = user;
                    next(); // repositoryのプロミスを直に参照して完了するまで次にいかない
                });
            },
            props: (route)=> {
                return {user: route.meta.user};
            },
        },
    ],
};
export default new Router(options);

 beforeEnterは公式ページで次のように紹介されています。

リダイレクトもしくはキャンセルによって遷移をガードするために主に使用されます。
ナビゲーションガード | Vue Router

 これは画面遷移を制御する仕組みです。この中でAPIを叩き、その結果が正常に終わるまで次の画面に遷移しない、というロジックを入れることによって同期処理的動作を実現できます。beforeEnterとpropsをつなぐのはrouteプロパティの一つのmetaです。このプロパティはany型でライブラリ呼び出し側(上位者)が好き勝手弄るための領域です。このプロパティは同一ルーティング処理内で使いまわされるため、上記例の様に値の受け渡しができます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG