はじめに
編集中に画面遷移をしようとしたときに、「編集中の内容があるが保存せずに移動していいか」を確認するモーダルを出したいという場面に遭遇し、Vue Routerのナビゲーションガードを使用しました。
実装を進めるなかで、Vue Routerのナビゲーションガードの種類、それぞれの使用法を学んだのでまとめます。
ナビゲーションガードとは
Vue Routerのナビゲーションガードは、ルートの遷移前後の処理を制御できる仕組みです。
主に、リダイレクト(別ページに強制移動)やキャンセル(ページ遷移を中断し、現在のページにとどまる)によってルートの遷移を防ぐために使用されます。
Vue Router のナビゲーションガードはVue Routerの仕組みであるため、Vue Router を通じたルート遷移でのみ発火します。
そのため、<a>タグを直接用いた場合、通常のHTMLナビゲーションとして処理され、Vue Router のガードが適用されません。
Vue Router のガードを機能させるには、<router-link> や router.push() を使用する必要があります。
ナビゲーションガードの種類
Vue Routerには以下3種類のナビゲーションガードがあります。
- グローバルガード
- ルート単位ガード
- コンポーネント内ガード
それぞれについて説明します。
グローバルガード
グローバルガードはアプリ全体のルート遷移に対して適用されるガードです。
3種類あり、それぞれ実行されるタイミングが異なります。
-
beforeEach
:ルート遷移前に実行 -
beforeResolve
:すべてのコンポーネント内ガードと非同期のコンポーネント読み込み終了後に実行 -
afterEach
:ルート遷移完了後に実行
const router = createRouter({ ... })
router.beforeEach((to, from) => {
// ...
// falseを返すことでナビゲーションをキャンセルできる
return false
})
それぞれのガード関数は、以下2つの引数を受け取ります。
どちらもルートオブジェクトです。
-
to
:遷移先のルート情報 -
from
:現在のルート情報
以下の戻り値を設定できます。
-
false
:ナビゲーション(ルート遷移)をキャンセルする -
ルートロケーションオブジェクト
:現在のナビゲーションをキャンセルし、router.push() のように新しいルートへの遷移を開始
router.beforeEach((to, from) => {
if (!isAuthenticated && to.name !== 'Login') {
return { name: 'Login' } // ログインページへリダイレクト
}
})
第3引数 next について
Vue Routerの以前のバージョン(v3)では、nextという第3引数が用いられていましたが、v4では推奨されていません。しかし、現在も使用可能となっています。
nextを使用する書き方は、以下の公式ガイドを参照してください。
ルート単位ガード
ルート単位ガードは、グローバルガード (beforeEach)とは異なり、特定のルート に対して設定するガードです。
-
beforeEnter
:特定のルート設定内で直接定義すると、そのルートに新しく入るときのみ実行される。
ただし、同じルートで params だけが変更される場合(例: /users/1 → /users/2)は発火しない。
以下の例では、ユーザーが /users/1 や /users/2 などにアクセスしようとするとナビゲーションがキャンセルされます。
const routes = [
{
path: '/users/:id', // 例: /users/1、 /users/2 など
component: UserDetails,
beforeEnter: (to, from) => {
// ナビゲーションをキャンセル
return false
},
},
]
コンポーネント内ガード
コンポーネント内ガードは、各コンポーネント内で定義するガードです。
特定のコンポーネントが表示・更新・削除されるときに処理を実行することができます。
コンポーネント内ガードは以下の3種類あります。
-
beforeRouteEnter
:
コンポーネントが表示される前に実行
コンポーネントが作成される前なので、this(コンポーネントのインスタンス)にはアクセスできない -
beforeRouteUpdate
:
コンポーネントが再利用されるとき(同じコンポーネントが使われたまま、URL のパラメータが変わったとき)に実行
例: /users/1 → /users/2 への遷移 -
beforeRouteLeave
:
コンポーネントから離れる前(異なるページに遷移するとき)に実行
ページを離れる前に確認メッセージを出すときに使用される
<script>
export default {
beforeRouteEnter(to, from) {
//...
},
beforeRouteUpdate(to, from) {
//...
},
beforeRouteLeave(to, from) {
//...
}
}
</script>
上記はOptionsAPIの書き方です。
Composition APIの場合は、以下を参照してください。
最後に
「編集中の内容があるが保存せずに移動していいか」を確認するモーダルを出したかったので、今回は beforeRouteLeave
のみを使用しましたが、これを機に初めてナビゲーションガードを学習することができました。
公式のドキュメントは英語で書かれていたり、難しかったりして避けてしまいがちでしたが、最新の情報を得るためには、公式ガイドを活用することが重要だと実感しました。
最後までお読みいただきありがとうございました!
参考