Search code examples
vue.jsvuejs2vue-routerhtml5-history

How do I go back to the last named route with a given name in Vue Router


Lets say I have 5 named routes, Index, News, TaggedNews, NewsItem, TaggedNewsItem

  • To change between various routes I call router.push and it is working properly
  • When I am at the NewsItem or TaggedNewsItem I want to go back to the last non item url, how do I do that
  • Take an example history stack like this Index News News TaggedNews TaggedNewsItem TaggedNewsItem
  • when I lclick a button I want to go from the last TaggedNewsItem by N steps where N will take me to the last named route TaggedNews or News or Index whichever comes first
  • how do I do this using Vue Router
  • It gives the option go(N) where N is the number of steps, problem is I need to find N to see where the last Index or News or TaggedNews item is present

Solution

  • I don't think the vue router saves the history stack. You would need to save it yourself.

    You can use vuex to keep track of the history stack and calculate the last different route path, and have it available everywhere you need.

    An implementation could be something like:

    history.js

    const history = {
        namespaced: true,
        state: {
            stack: [],
        },
        mutations: {
            PUSH_STACK(state, routeName) => state.stack.push(routeName),
        },
        actions: {
            pushStack({ commit }, routeName) => commit('PUSH_STACK', routeName),
        },
        getters: {
            lastDiff(state) {
                const reversed = state.stack.slice().reverse();
                const diff = reversed.findIndex(route => route !== reversed[0]);
                return -1 * diff;
            }
        }
    }
    export default { history }
    

    store.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import { history } from './history';
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
        modules: {
            history
        }
    })
    export default { store }
    

    Include it in your main.js file:

    import Vue from 'vue';
    import { store } from './store';
    
    const app = new Vue({
        el: '#app',
        store
    });
    

    In your router file, you can add a global after hook to push the path name to the store like this:

    import { store } from './store';
    
    const router = // router config
    
    router.afterEach((to) => store.dispatch('history/pushStack', to.name));
    

    And in your components you can use it like this:

    const backN = this.$store.getters['history/lastDiff'];
    this.$router.go(backN);