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型でライブラリ呼び出し側(上位者)が好き勝手弄るための領域です。このプロパティは同一ルーティング処理内で使いまわされるため、上記例の様に値の受け渡しができます。