LoginSignup
10
8

More than 3 years have passed since last update.

【Vue.js】ナビゲーションガード(beforeRouteEnter)を使って前のページのURLを取得する

Posted at

やりたいこと

VueRouterで遷移するページで、一つ前のページのURLなどを取得して、
それに応じてページ内のパーツの表示非表示を切り替えたい。

beforeRouteEnterで取得しようとしたが・・・

今回はあるComponentのみで、前のURLが必要だったので、VueRouterのナビゲーションガードのbeforeRouteEnterを使用してみました。
公式のドキュメント

hogeComponent.vue
<template>
  <div>
    // 前のURLに応じてここの表示非表示を切り替えたい
    <div v-if="prevRoute.name =='hoge'"></div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      prevRoute: null,
    };
  },
  created() {
  },
  beforeRouteEnter(to, from, next) {
    next(vm => {
      vm.prevRoute = from;
      console.log(vm.prevRoute);
    });
  },
  methods: {
  }
};
</script>

これでthis.prevRoute.name前のページで表示していたComponentの名前
this.prevRoute.path前のURLが取得できます。

しかし、ここで一つ問題が・・・!
nextに渡したコールバック関数はVueライフサイクルフックのmountedよりも後に実行されてしまうので、
ページを描画するタイミングではprevRoute.nameprevRoute.pathが存在しませんよ〜
というエラーが出てしまう。。。。
beforeRouteEnterのnextコールバックの実行タイミングはこちらの記事を参考にさえていただきました。
ちなみに、コンポーネント描画後であれば、this.prevRoute.nameなどで取得できます!

Vuexを使ってみる

そこで、beforeRouteEnterで取得した前のページのデータをVuexのStateで管理し、
computedでVuexのStateからデータを取得するという方法をとる事にしました。
もっと簡単な方法があればぜひ教えてください・・・!

hogeComponent.vue
<script>
//省略
  beforeRouteEnter(to, from, next) {
    // ここでVuexに前のページの情報をStateに渡す!!
    next(vm => {
      vm.prevRoute = from;
    });
  }
</script>

実装方法

hogeComponent.vue

<script>
import store from "../../../store/index";
import { mapMutations, mapGetters } from "vuex";

export default {
  data() {
    return {
      prevRoute: null
    };
  },
  beforeRouteEnter(to, from, next) {
    store.commit("route/setPrevRoute", from);
    next(vm => {
      vm.prevRoute = from;
    });
  },
  computed: {
    prevRouteChild() {
      return this.$store.getters["route/getPrevRoute"];
    }
  }
};
</script>
store/modules/route.js
const state = {
    prevRoute: []
};

const mutations = {
    setPrevRoute(state, from) {
        state.prevRoute = from;
    }
};

const actions = {};

const getters = {
    getPrevRoute: state => state.prevRoute
};

export default {
    namespaced: true,
    state,
    mutations,
    getters,
};
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import route from "./modules/route";

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        route
    }
});

これで初期描画のタイミングで表示非表示を切り替えることができました!
何か間違ってたら、是非教えてください^^

参考ページ

beforeRouteEnterのnextコールバックの実行タイミング

10
8
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
10
8