Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrent route props in beforeRouteEnter when using <transition> #2062

Closed
mrnateriver opened this issue Feb 14, 2018 · 7 comments
Closed

Incorrent route props in beforeRouteEnter when using <transition> #2062

mrnateriver opened this issue Feb 14, 2018 · 7 comments
Labels

Comments

@mrnateriver
Copy link

Version

3.0.1

Reproduction link

http://jsfiddle.net/L7hscd8h/3877/

Steps to reproduce

  1. Open provided jsfiddle.net link;
  2. Open browser console;
  3. Click on 'first a' ;
  4. Click on 'first b' ;
  5. Click on 'second a' ;
  6. Click on 'first a' again;
  7. Inspect console output.

What is expected?

Component props should be set to ones defined in route in beforeRouteEnter hook even when transitions are used.

Expected output:

vue-component-3: mounted
vm.title: first_a
vm.title: first_b
vue-component-4: mounted
vm.title: second_a
vm.title: first_a
vue-component-3: mounted

What is actually happening?

It seems that props are set after the transition is finished, as well as the mounted hook is called. The connection between those two is easily determined by looking at the order of console output with or without transition tag (like at this slightly modified JSFiddle: http://jsfiddle.net/L7hscd8h/3878/).

Actual output:

vue-component-3: mounted
vm.title: first_a
vm.title: first_b
vue-component-4: mounted
vm.title: second_a
vm.title: first_b   <--- the problem
vue-component-3: mounted

I presume this issue has something to do with Vue reusing components (which had only been a pain in the head for me), since it doesn't occur when switching routes with the same component.

It is undeniably vital for correct values of props to be available in beforeRouteEnter since they can be used to fetch data asynchronously for components. Or, if you like, not fetching, but sending.

Used versions:
vue-router 3.0.1 (sha512-vLLoY452L JBpALMP5UHum9 7nzR9PeIBCghU9ZtJ1eWm6ieUI8Zb/DI3MYxH32bxkjzYV1LRjNv4qr8d uX/w==)
vue 2.5.13 (sha512-3D lY7HTkKbtswDM4BBHgqyq qo8IAEE8lz8va1dz3LLmttjgo0FxairO4r1iN2OBqk8o1FyL4hvzzTFEdQSEw==)

@posva posva added the bug label Feb 14, 2018
@posva
Copy link
Member

posva commented Feb 14, 2018

Note to myself: make sure it comes from vue-router and not from vue's transition

@soanvig
Copy link

soanvig commented Feb 20, 2018

This is quite strange issue.

  1. Click on first b
  2. Click on second a
  3. click on first b
  4. click on second a

Result:

vue-component-3: mounted
vm.title: first_b
vue-component-4: mounted
vm.title: second_a
vue-component-3: mounted
vm.title: first_b
vue-component-4: mounted
vm.title: second_a

So now it works.

Moreover, if reproducing just like @mrnateriver said I get following results:

vm.title: first_a
vm.title: first_b
vue-component-4: mounted
vm.title: second_a
vm.title: first_b
vue-component-3: mounted

which is very strange, because as the last click I clicked "first a", not "first b".

@soanvig
Copy link

soanvig commented Feb 20, 2018

After more testing:

Clicking: 1a, 1b, 2a, 1a leads to bug, that displays: 1b, mounted
Clicking: 1a, 1b, 2a, 1b displays: mounted, 1b
Clicking: 1b, 1a, 2a, 1b leads to bug, that displays: 1a, mounted

So what exactly is bugged?

It seems, that after switching from component 1 to component 2, 1's last state gets cached.
Then, after switching again to component 1 from component 2, 1's last state cache is used.

If 1's last state cache isn't diffferent from the new cache (it means, that before leaving component we were on state "A", and we are returning to state "A") everything works at it should: mounted hook is executed before beforeRouteEnter.

But if 1's state cache differs from new state (before leaving component we were on state "B", and we are returning to state "A") things get broken, and beforeRouterEnter is called before mounted plus it uses state "B" (last cached state) anyway. Watcher on title doesn't execute either.

According to:
https://router.vuejs.org/en/advanced/navigation-guards.html
beforeRouteEnter is called before mounted, but using next from test case 'moves' that behavior to the end of flow.

The bug is present only in logged values, if we try to display the prop in DOM it works as it should (after clicking "A" we get "A" - not "B" - in DOM).

@mrnateriver
Copy link
Author

The bug is present only in logged values, if we try to display the prop in DOM it works as it should (after clicking "A" we get "A" - not "B" - in DOM).

Just to be clear - this bug affects not only logging of those values, but also using them for any operation in general, i.e. fetching data. My guess is that the value is displayed correctly as prop because arguments for the hook are taken from the component instance which is updated after the hook is called, but before component is re-mounted.

Thought to emphasise that so that people who stumble upon this issue don't underestimate its significance.

@pschaub
Copy link

pschaub commented Feb 23, 2018

This is a huge issue because mostly these hooks are used to check if a user is allowed to enter the page (e.g. do not show internal routes if user is not logged in) so this bug could result into a very broken app behaviour for some users and is not easy to be tracked. I hope that somebody will find a solution soon.

@philippeluickx
Copy link

Not sure if my issue is related, but it looks like the closest so far.
I try to change the value of a property I pass down to my child with props <router-view :test="test"></router-view>. If I change the value in the beforeLeave transition hook, it gets updated in the parent, not in the child, even though props should be reactive.

@posva
Copy link
Member

posva commented Jul 9, 2018

This doesn't seem to be a problem anymore. Was probably fixed in #2127 (not released yet)
But there's still #2188

@posva posva closed this as completed Jul 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants