2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Vue.Router】ナビゲーションガード

Last updated at Posted at 2021-12-15

ナビゲーションガード

  • クリック後にコンポーネントが切り替わる間に処理を実行できる機能。
  • ライフサイクルフックのようなイメージ

3つの書き方

グローバルコンポーネントビフォーガード

  • 全てのルートに適用される。
  • 認証系の手続きで使う事がある。
  • routerのインスタンスに直挿
router/index.js
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

ルート単位ガード

  • 直接ルート設定オブジェクトの beforeEnter ガードを定義することができます。
const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

コンポーネント内ガード

  • ルートコンポーネント(ルータ設定に渡されるもの)の内側でルートナビゲーションガードを直接定義する

  • beforeRouteEnter

  • beforeRouteUpdate (2.2 で追加)

  • beforeRouteLeave

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // このコンポーネントを描画するルートが確立する前に呼ばれます。
    // `this` でのこのコンポーネントへのアクセスはできません。
    // なぜならばこのガードが呼び出される時にまだ作られていないからです!
  },
  beforeRouteUpdate(to, from, next) {
    // このコンポーネントを描画するルートが変更されたときに呼び出されますが、
    // このコンポーネントは新しいルートで再利用されます。
    // たとえば、動的な引数 `/foo/:id` を持つルートの場合、`/foo/1` と `/foo/2` の間を移動すると、
    // 同じ `Foo` コンポーネントインスタンスが再利用され、そのときにこのフックが呼び出されます。
    // `this` でコンポーネントインスタンスにアクセスできます。
  },
  beforeRouteLeave(to, from, next) {
    //ページ遷移するときなど
  }
}

beroreTouteLeaveを使用したcase

  • ページを離れる時に「本当にこのページを離れますか?」という確認をユーザーに即すときなどに使う。
some.vue
/*
.
省略
*/
<script>
export default {
  name:'About',
  beforeRouteLeave(to, form, next){
    const checkLeave = window.confirm('本当にこのページを離れますか?')
    if(checkLeave){
      next()
    }else {
      next(false)
    }
  }
</script>

ezgif.com-gif-maker (5).gif

to, from, nextとは

  • to :Routeオブジェクト
    • 新しい遷移先のオブジェクトを返す。
  • from: Routeオブジェクト
    • 遷移前のオブジェクトを返す。
  • next: Function
    • ナビゲーションガードの最後にnext()関数を呼び出す。
    • next()関数を呼ばないと、コンポーネント間のパイプラインが終了できない。
    • 結果として描画されないようになる。
  • next()の引数
    • next()
      • 処理のパイプラインが完了し次のフックに移動する。
    • next(false)
      • 現在のナビゲーションを終了させ、ブラウザのurlが変化した場合はfromルートに戻る。
    • next('/') or next({path: '/'})
      • 現在のナビゲーションが終了。
      • 任意のロケーションをnextに以下のようにセットできる。
        • replace: true
        • name: 'home'
        • router-link
        • toプロパティ
        • router.pushで使用される任意のオプション
    • next(error)
      • ナビゲーションは中止
      • 引数に渡されたものがErrorインスタンスの場合error.onError()を介して登録されたコールバック関数が渡される。
  • next()関数は一度だけ呼ばれるようにする。
    • 2回呼ばれる場合はerrorになる。
    • 2回呼ばれるようなコードの書き方
// 2回呼ばれる悪いケース
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // ユーザーが認証されていない場合、 `next` は2回呼ばれる
  next()
})
// 修正したコード
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

まとめ

スクリーンショット 2021-12-16 20.20.54.png

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?