Vue-router: Catch cancelled navigations

Created on 19 Jan 2018  ·  7Comments  ·  Source: vuejs/vue-router

What problem does this feature solve?

This will allow users to hook on:

  • redirections to the current route (could be a different hook like onRedirect, also triggered by redirect option)
  • next(false) calls
  • navigation delayed and replaced by other navigations:

    • eg: users click when async component not finished loading

I'm a bit sceptical about use cases on why to hook on redirects, so I'll love to read if you have usecases

What does the proposed API look like?

router.onCancel((to, from, currentLocation) => {
  // from -> original route where the navigation was triggered
  // to -> where was it supposed to go
  // currentLocation -> location where we ended up (same as this.$route in components and router.currentRouter
})

can be triggered by

router.beforeEach((to, from, next) => {
  next(false) // cancel navigation explicitely
})

router.beforeEach((to, from, next) => {
  to.fullPath // /foo
  from.fullPath // /home
  // redirect to /home if we're on /foo
  // this will do nothing if we are already on /home
  if (to.fullPath === '/foo') next('/home')
  else next()
})
feature request fixed on 4.x

Most helpful comment

All 7 comments

@posva When we can expect this? Im just asking :)

It depends on how much time I can allocate to open source but this one needs more thinking because redirecting can happen in different situations and not all are considered the same (in navigation guard vs in route record). As I'm working on the next version of Vue Router I may find other suitable APIs.
I won't be able to work on this anytime soon unfortunately

Thank you very much for response :)

There is an RFC that solves this https://github.com/vuejs/rfcs/pull/150

One related question, is it possible to force a router.push? As in force it not to be cancelled? I have some edge case where the user submits a form and this triggers a redirect I need to force this redirect to not be cancelled, because it can happen that while the redirect occurs, an other router.push is triggered at the exact same time in a completely unrelated code: I have a section observer pushing the current hash/id of the section to the router. So basically if you scroll while submitting you may not get redirected..

I'm thinking something like this.$router.push({name: 'foo', {force: true}); or on the other code

if (!this.$router.isPending) {
  this.$router.push({name: 'bar', {hash: 'baz'});
}

@posva It seems the pending property could do the trick in the base history, but it doesn't seem to be exposed through a public router api so right now I am able to do
this.$router.history.pending === null, but with no guarantee it will continue to work

@Tofandel A pendingLocation could indeed be exposed, it's worthy of an RFC to discuss if it should unset once a navigation is done, different solutions and problems that may arise. It can be implemented in user land with a combination of router.beforeEach, router.afterEach and router.onError

Was this page helpful?
0 / 5 - 0 ratings