🛡️

Vue Routerで遷移先のメソッドを遷移情報を条件にして呼ぶ

2022/10/21に公開

Vue Router を用いた Vue.js アプリ開発をしていて、「特定のコンポーネントからページ遷移して来た場合だけ、遷移先のコンポーネントのメソッドを実行したい」というようなシチュエーションがありました。幸い、Vue Router には URL の遷移をフックとした処理を行う仕組みとして「ナビゲーションガード」が用意されています。その書き味は created()mounted() などの Vue.js のライフサイクルフックに似たものがあるので、とっつきやすいでしょう。

これから説明することはVue Router の公式ガイドに書いてある内容ですが、利用シチュエーションがありそうな割に言及しているWebサイトが私の力では見つからなかったので、取り上げたいと思います。

結論のコードを示します。今回使う beforeRouterEnter() は遷移先のコンポーネントのインスタンスが作成される前にフックされるため、this でインスタンスにアクセスすることができません。その代わり、遷移処理を実行する next にコールバックを渡すと、コールバック引数からインスタンスにアクセスすることができます。

遷移先でonUpdate()を呼ぶ
  beforeRouteEnter (to, from, next) {
    if (from.name === 'Menu') {
      next((vm) => {
        vm.onUpdate() // called!
      })
    } else {
      next()
    }
  },
  methods: {
    onUpdate() {
      console.log('called!')
      ...
    },
    ...
  }

この例では、遷移元のコンポーネントにつけている名前が「Menu」なら、遷移先のコンポーネントに定義されている onUpdate() メソッドを実行し、遷移を実行しています。beforeRouteEnter を使えば、遷移元または遷移先の情報を条件とした遷移先の任意の処理の実行が可能です。

なお、ガイドでは次のように説明されています。

この beforeRouteEnter ガードは this へのアクセスはできないです。なぜならば、ナビゲーションが確立する前にガードが呼び出されるからです。したがって、新しく入ってくるコンポーネントはまだ作られていないです。

しかしながら、 next にコールバックを渡すことでインスタンスにアクセスすることができます。このコールバックはナビゲーションが確立した時に呼ばれ、コンポーネントインスタンスはそのコールバックの引数として渡されます。

ガイドのサンプルコード
beforeRouteEnter (to, from, next) {
  next(vm => {
    // `vm` を通じてコンポーネントインスタンスにアクセス
  })
}

Discussion