前回の記事に引き続き、Vue Routerについての記事となります。
Vue Routerでアクセス制限を実現する
今回は、ナビゲーションガードを利用したアクセス制限を実現するコードを解読していきます。実現したいのは、「特定のパスに対してアクセス制限をかける」ことです。
今回は、コードの中核部分を『基礎から学ぶVue.js』(およびそのサポートページ)に負っています。初心者にわかりやすく、また実践的でもあり、そしてサポートページが実に充実している書籍です。ありがたい。

- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
今回のコードを置いているGitHubリポジトリはこちら(すでに更新が加わっています)。このリポジトリに限らず、コードの書き方等に指摘あればぜひお知らせください!
Vue Routerの設定とナビゲーションガードの導入
前回、Vuer Routerの設定は以下のようにしていました。
let router = new VueRouter({ routes: [ { path: '', component: Top, children: [ { path: '', component: ChildA, name: 'childA' }, { path: '/childB', component: ChildB, name: 'childB', meta: { requiresAuth: true } } ] }, { path: '/helloworld/:msg', component: HelloWorld, name: 'helloworld' } ] });
/childB
というパスに対して、meta要素にrequiresAuth: true
を指定しています。この要素を利用して、認証が必要なパスと不要なパスとを区分していきます。
ナビゲーションガード(グローバルガード)のコード
ナビゲーションガードを導入します。利用するのは「グローバルガード」です。
今回記載したソースコードは下記のようなものです。こちら、ほぼ『基礎から学ぶVue.js』記載のコードとなっています。
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { if (!store.state.isLogin) { next({ path: '/', query: { redirect: to.fullPath } }) } else { next(); } } else { next(); } });
このコードを読み解いてみます。
Vue Routerの様々なオブジェクト
router.beforeEach()
は、ルーターインスタンスのメソッドで、画面遷移前に実行される処理を引数に記載します。処理の中では、遷移先をnext()
で指定します。上の例の場合、一定の条件下でリダイレクトさせるために利用しています。
次に、ifの条件となっているto.matched.some(record => record.meta.requiresAuth)
についてです。to
は、遷移先を示すルートオブジェクトです。単なる文字列ではありません。公式ドキュメントの記述を引用します。
遷移先のURLの、現在の URL をパースした情報と、その URL とマッチしたルートレコードを保持しています。ルートレコードは
routes
設定の配列 (とchildren
配列) 内のオブジェクトのコピーです。
matched
は、ルートポブジェクトのプロパティで、この「現在のルートのネストされた全パスセグメントに対しての ルートレコード を保持している配列」です。
この場合、VueRouterのコンストラクタに渡しているオブジェクトのroutes
配列の1つ目の要素(path: ''
の部分)と、その中のchildren
配列の2つ目の要素(path: '/childB'
の部分)とを要素とする配列ということになります。
Array.prototype.some()
そして、some()
メソッドはArray.prototype.some()
です。
some()
メソッドは、to.matched
という配列の各要素をそれぞれrecord
として扱い、record.meta.requiresAuth
が真となる要素があれば真を返します。今回の場合、childB側の要素が条件に合致するため、some()
メソッドが真を返し、認証の確認部分が実行されるというわけですね。
※今回の例では、requiresAuth: true
と指定しているchildBがネストの最下位ですが、some()を利用することで、上位のパスにrequire
sAuth: true
を指定されていれば認証確認の対象となります。
認証の確認とリダイレクト、そしてVuexへ
認証確認部分はシンプルです。if(!store.state.isLogin)
でログインしているかどうかを確認し、ログインしていなければnext()
の引数(ルートオブジェクト)で認証不要なパスを指定します。上記の例では、クエリ文字列でリダイレクト元(本来の、許可されなかった遷移先)の情報を付加しています。
以上によって、「特定のパスにアクセス制限をかける」ことが実現できました。そのまま使えるサンプルコードや、親切な解説書の存在はとてもありがたいですが、その先で自力でAPIドキュメントを読んでみると、理解度が全然違いますね。Array.prototype.some()
も、今回はじめて知りました。
今回は、Vue Routerのナビゲーションガードを用いて特定のパスにアクセス制限をかけてみました。今回用いたのはグローバルガードと呼ばれる最も基本的なナビゲーションガードでしたが、他の種類のナビゲーションガード、あるいはナビゲーションガード以外のVue Routerの機能も少しずつ試していきたいと思います。
また、ちらっと登場したstore.state.isLogin
は、実はVuexを利用しています(アクセスの仕方がこれでいいのかは不明・・・)。まだVuexは消化不良なのですが、ある程度の段階で記事にまとめようと思います!

- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/30
- メディア: 大型本
- この商品を含むブログを見る