69

I want to get previous page link or url in vue-router. Like a this. How to do it?

const link = this.$router.getPrevLink(); // function is not exist?
this.$router.push(link);

Near concept is this.$router.go(-1).

this.$router.go(-1);
arai
  • 1,251
  • 2
  • 12
  • 17

7 Answers7

106

All of vue-router's navigation guards receive the previous route as a from argument ..

Every guard function receives three arguments:

  • to: Route: the target Route Object being navigated to.

  • from: Route: the current route being navigated away from.

  • next: Function: this function must be called to resolve the hook. The action depends on the arguments provided to next

As an example you could use beforeRouteEnter, an in-component navigation guard, to get the previous route and store it in your data ..

...
data() {
 return {
   ...
   prevRoute: null
 }
},
beforeRouteEnter(to, from, next) {
  next(vm => {
    vm.prevRoute = from
  })
},
...

Then you can use this.prevRoute.path to get the previous URL.

Husam Ibrahim
  • 6,999
  • 3
  • 16
  • 28
  • 26
    **Note**: That you can only use `beforeRouteEnter` in the component that the route is defined for and not a child component which is not defined in the router. – hitautodestruct Aug 01 '19 at 12:00
  • @hitautodestruct Then adding it as a global mixin wouldn't be a good idea since components that don't have a route would mess up ?! – lbris Mar 12 '20 at 11:03
  • @Husam Ibrahim Also what is the advantage of this method compared to the `.go(-1)` ? – lbris Mar 12 '20 at 14:13
  • 4
    @Ibris The OP asked for a way to get the URL of the previous page (I don't know the details of their use case). If you simply want to go to the previous page then `this.$router.go(-1)` is the way to go ;) – Husam Ibrahim Mar 12 '20 at 20:10
  • 6
    Say I directly navigate to the SPA by copying and pasting the link in the browser, `this.$router.go(-1)` is not suitable in this case. – Micheal J. Roberts May 18 '20 at 09:45
  • This does not work for me, I get the **error message**: `[Vue warn]: Error in the mounted hook:" TypeError: this.prevRoute is null "` when trying to get `this.prevRoute.path` from the console. Confusing is the fact that `console.log (this)` correctly displays `prevRoute`. @HusamIbrahim – Tenarius Jul 14 '20 at 08:29
  • 1
    @Tenarius Seems that this is the expected behavior because `next` callbacks are invoked after a `nextTick`. So you can't access properties set by the callback in `created`/`mounted` because these hooks come earlier. See [this issue](https://github.com/vuejs/vue-router/issues/1144). – Husam Ibrahim Jul 14 '20 at 10:25
  • is there `beforeRouteEnter` in Vue 3? – Sabbir Sobhani Mar 22 '22 at 12:45
33

For Vue 3 with Vue Router 4, my solution was:

this.$router.options.history.state.back

The final code:

export default defineComponent({
  name: 'Error404',
  data () {
    return {
      lastPath: null
    }
  },
  created () {
    this.lastPath = this.$router.options.history.state.back
  },
  computed: {
    prevRoutePatch () {
      return this.lastPath ? this.lastPath : '/dashboard'
    }
  }
})

Regards.

Kalnode
  • 9,386
  • 3
  • 34
  • 62
  • 4
    For Vuejs 3, First `import { useRouter } from "vue-router";` Second invoke the `router` instance `const router = useRouter();` then for example: `router.options.history.state.back ` works like cake! – Sabbir Sobhani Mar 22 '22 at 12:39
  • vue-router v4.0.16: `router.options.history.state['back']` – Anna Madsen Apr 27 '23 at 08:38
6

This routing solution will fall back to a static url if a previous url does not exist.

<template>
    <div>
        <router-link :to="prevRoutePath">Previous Page</router-link>
        <router-link to="/">Home Page</router-link>
    </div>
</template>

<script>
export default {
    beforeRouteEnter(to, from, next) {
        next(vm => {
            vm.prevRoute = from;
        });
    },
    computed: {
        prevRoutePath() {return this.prevRoute ? this.prevRoute.path : '/'},
    }
}
</script>
Liakos
  • 512
  • 5
  • 10
4

Though this answer is great, the received route wouldn't always be the route before in history in case of popstate navigations (aka when the user clicks the back button).

So if you use Vuex here's a code snippet that respects this behavior:

const store = new Vuex.Store({
  state: {
    routerHistory: [],
  },
});

const router = new VueRouter({
  mode: 'history',
  scrollBehavior(to, from, savedPosition) {
    const fromHistory = Boolean(savedPosition);

    if (fromHistory && store.state.routerHistory.length > 0) {
      store.state.routerHistory.splice(-1, 1);
    } else {
      store.state.routerHistory.push(from);
    }

    return savedPosition || { x: 0, y: 0 };
  },
});

Once implemented, you can define a getter for the previous route inside your store:

const store = new Vuex.Store({
  // ...
  getters: {
    previousRoute: (state) => {
      const historyLen = state.routerHistory.length;
      if (historyLen == 0) return null;
      return state.routerHistory[historyLen - 1];
    },
  },
});

This code uses the scrollBehavior hook, which only receives the savedPosition argument if it was a popstate navigation. Thanks to Vuex we can then store all the routes in an array (over multiple pages).

garzj
  • 2,427
  • 2
  • 8
  • 15
1
<template>
    <div>
        <router-link :to="previousPage">Previous Page</router-link>
        <router-link to="/">Home Page</router-link>
    </div>
</template>

<script setup>
    import { useRouter } from 'vue-router';
    import { computed } from 'vue';

    const router = useRouter();

    const previousPage = computed(() => {
        const lastPath = router.options.history.state.back;
        return lastPath ? lastPath : '/';
    });
</script>
Kurowsky
  • 154
  • 1
  • 9
0

For Vue 2.6 that works for me:

In-App.vue component when you initialize the VueRouter you can get from and to details as below:

export const globalState = Vue.observable({ from: {}, to: {} });
const router = new VueRouter({
    base: '/',
    routes: routes,
    mode: 'history',
    scrollBehavior(to, from, savedPosition) {
        Vue.set(globalState, 'from', from);
        Vue.set(globalState, 'to', to);
        return { x: 0, y: 0 };
    },
});

routes are ur routes and each time u navigate to a different URL you will have all from and to routes details. Then u can import the globalState object and use it like that

     import { globalState } from './app';
     goBack() {
        const lastPath = globalState.from?.fullPath;
        const currentPath = globalState.to?.fullPath;
        if (lastPath && currentPath !== lastPath) 
           {
              this.$router.push(lastPath);
           } else {
              this.$router.push('another-path');
            }
        }
Amr Omar
  • 399
  • 5
  • 12
-1

To yank it right out of the $router object, use this in your computed or methods:

lastRouteName: function() {
  let returnVal = '';

  const routerStack = this.$router.history.stack;
  const idx = this.$router.history.index;

  if (idx > 0) {
    returnVal = routerStack[idx - 1].name;
  }

  return returnVal;
}

That'll return the route name, but you can also return the .path or whatever other property if you like.

To inspect the history object, do console.log(this.$router.history);

JohnM_3948
  • 17
  • 3