Vue-router: beforeRouteUpdate not called if different route uses same component

Created on 10 Nov 2017  路  6Comments  路  Source: vuejs/vue-router

Version

3.0.1

Reproduction link

https://jsfiddle.net/50wL7mdz/75563/

Steps to reproduce

1 - click first on the router-link "edit 1"
2 - click on router-link "edit 2"
3 - click on router-link "create"

What is expected?

1) the form component will be first mounted with id = 1
2) the function beforeRouteUpdate will be called with id = 2
3) the function beforeRouteUpdate will be called with id = null and isCreate = true

What is actually happening?

Actually, after clicking the router-link create(step 3), the function beforeRouteUpdate won't be called.


I found out that beforeRouteUpdate will be called only when changing params to the same route, not when changing the whole route.
But since i use the same form for editing and creating a resource, wouldn't it be nice to call beforeRouteUpdate anyway?
If it's not possible, is there another way to do it (maybe without watching the $route in the component)?

Most helpful comment

I do not use params, and instead just change the entire route path while reusing the same component, like so:

{ path: "/", name: "about", component: MarkdownPage, meta: { title: "tenrys.pw - About" }, props: { pagename: "about" } },
{ path: "/contact", name: "contact", component: MarkdownPage, meta: { title: "tenrys.pw - Contact" }, props: { pagename: "contact" } },

I want to use beforeRouteLeave in order to cancel route switching if a condition is met but it does not always get called for some reason:

for example, if I start the page on "/" route, and switch to "/contact", it will get called properly. If I try to switch back to "/", it will not get called. All this without reloading.

Am I using Vue Router wrong?

beforeRouteEnter is not acceptable since I do not have access to this.

All 6 comments

That's expected: beforeRouteUpdate is called when one of the params change. If the route changes you have to use beforeRouteEnter

Extra note: beforeRouteUpdate is called when the route changes but a currently displayed route record still matches the url. eg: one of the params change, a parent route being reused because only the child changes. If the route changes, no matter if the component is being reused by Vue, if it's a different route record, you have to use beforeRouteEnter

I do not use params, and instead just change the entire route path while reusing the same component, like so:

{ path: "/", name: "about", component: MarkdownPage, meta: { title: "tenrys.pw - About" }, props: { pagename: "about" } },
{ path: "/contact", name: "contact", component: MarkdownPage, meta: { title: "tenrys.pw - Contact" }, props: { pagename: "contact" } },

I want to use beforeRouteLeave in order to cancel route switching if a condition is met but it does not always get called for some reason:

for example, if I start the page on "/" route, and switch to "/contact", it will get called properly. If I try to switch back to "/", it will not get called. All this without reloading.

Am I using Vue Router wrong?

beforeRouteEnter is not acceptable since I do not have access to this.

To sum up, we must use both beforeRouteUpdate and beforeRouteEnter.

So a navigation guard is missing! As exact opposite of beforeRouteLeave and handling params update and other case of route changement:

Something like afterRouteChange

Where this is available.

@Tenrys vuejs nav-guards documentation says that you actually have access to vm like this:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // access to component instance via `vm`
  })
}

But on my personal testing in my case, beforeRouteEnter doesn't work quiet well. It is just sometimes fires function passed to next, sometimes not. While it must always fire.

I think the problem is with next in beforeRouteEnter function with vm passed to next must be fired everytime beforeRouteEnter fired too. While it fires only once or something like that, which is wrong.

Hi, try to use beforeRouteEnter and beforeRouteUpdate together like below:

function beforeEnter (to, from, next) {
  // do things
  next()
}

export default {
 beforeRouteEnter (to, from, next) {
   beforeEnter(to, from, next)
  },

 beforeRouteUpdate (to, from, next) {
   beforeEnter(to, from, next)
  }
}
Was this page helpful?
0 / 5 - 0 ratings