What is it, naokirin?

Vue Router で遷移前、遷移後に処理を行う

最近はもっぱら電子書籍を買うことが多くなりましたが、物理スペースを気にせず一気に買えるので、積み本が増えてしまっている今日このごろです。

今日は、Vue.js の Vue Routerを使う際に、「遷移時に毎回処理をしたい」といったことがあったので、その際に利用した「ナビゲーションガード」について書いておきます。

詳しい使い方は、以下に書いてあります。

router.vuejs.org

先に結論

  • グローバルに設定したいなら、 router.beforeEach((to, from, next) => { ... })router.afterEach((to, from) => { ... })を使う
    • 2.5.0 以降なら、 router.beforeResolve((to, from, next) => { ... }) で他のガードや非同期ルートコンポーネント解決後に呼ばれる機能が使える
  • コンポーネント単位で設定したいなら、 beforeRouteEnter(to, from, next) { ... }beforeRouteLeave(to, from, next) { ... } を定義する
  • ルート設定でも beforeEnter で設定は可能

コンポーネント単位の設定

グローバル定義も便利ですが、全てで必ず呼ぶようなことはそこまで多くなさそうなのと、Vue Routerを使う場合はルートコンポーネントに指定してあるほうがわかりやすそうなので、コンポーネント単位の設定のみ記載します。

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    console.log("[ENTER] To: " + to.path, + " From: " + from.path);
    next();
  },
  beforeRouteUpdate(to, from, next) {
    console.log("[UPDATE] To: " + to.path, + " From: " + from.path);
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log("[LEAVE] To: " + to.path, + " From: " + from.path);
    next();
  }
}

こんなふうにコンポーネント描画のルートに入る前や、更新前、抜ける前に呼び出される関数を定義できます。

beforeRouteEnter

beforeRouteEnter はナビゲーション確立前のコンポーネントインスタンスが作成される前に呼び出されます。

そのため、 this に直接アクセスすることができない点に注意する必要があります。

これに対する解決は、 next に関数を渡して作成後のインスタンスを受け取って処理をすることでできます。

beforeRouteEnter(to, from, next) {
  // vmがコンポーネントインスタンスなので、メソッド等を呼ぶことができる。
  next(vm => { vm.initialize(); });
}

beforeRouteLeave

beforeRouteLeave はこのコンポーネントがナビゲーションから離れるときに呼ばれます。

このときは、まだコンポーネントインスタンスが存在しているため、 this を使うことができます

この beforeRouteLeavenext には、boolean値を渡すことができ、ここで false を渡すことで、ナビゲーションの取り消しができます。

beforeRouteEnter(to, from, next) {
  // ナビゲーションの飛び消しをする
  next(false);
}

beforeRouteUpdate

beforeRouteUpdate は、同一コンポーネントのナビゲーションで呼ばれます。

再利用される際にはこちらを使う必要がある点には注意が必要です。

例えば /users/1/users/2 のような動的セグメントを使ったルーティングで発生します。

こちらも、インスタンスは生成済みのため、 this が利用できます

beforeRouteUpdate(to, from, next) {
  next();
}

まとめ

ナビゲーションでの遷移時に処理をしたい場合は、ナビゲーションガードが利用できます。