Vue-router: Race Condition between DOM Update and Routing to New Page

Created on 13 Aug 2016  路  8Comments  路  Source: vuejs/vue-router

Vue.js & vue-router.js version

2.0.0-rc.1, 2.0.0-rc.3

Reproduction Link

http://codepen.io/analog-nico/pen/KrJgqN

Steps to reproduce

  1. Check the "I agree" checkbox
  2. Click "Sign Up"
  3. The router successfully navigates to the second page
  4. Click "Go back"
  5. Leave the "I agree" checkbox unchecked
  6. Click "Sign Up"
  7. An error message above the checkbox is shown
  8. Check the "I agree" checkbox
  9. Click "Sign Up"

    What is Expected?

  • Again, the router should successfully navigate to the second page.

    What is actually happening?

  1. Vue.js is rebuilding the DOM after this.errorAgreement = false was set and thus the DOM element for the error message gets removed. All DOM elements below the error message get reinserted.
  2. While the rebuilding takes place self.$router.push({ path: '/done' }) is executed and - i guess - starts to destroy the page in order to navigate to the second one.
  3. Vue.js produces an error because it wants to insert a node before another node that doesn't exist anymore: "NotFoundError: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist."
  4. The crash is visible by the two "Sign Up" buttons that appeared. The first one was newly inserted. The second one is the original one which would have been removed if Vue.js hadn't crashed.

Most helpful comment

@fnlctrl No problem! Weeding out the usage issues is important to keep the workload manageable. Especially for a project with this much attention. Btw, I am happy to see that you are part of a healthy core maintainer group of the library I so much love and depend on. Thank you!

All 8 comments

Still occurs with vue 2.0.0-rc.3 and vue-router 2.0.0-rc.3: http://codepen.io/analog-nico/pen/yJmNYy

I've removed irrelevant code in your repro (and please please do this yourself next time), the bug appears no more.
http://codepen.io/fnlctrl/pen/pbrpEO
So I guess there's something wrong in your code, please do the debug yourself.

@fnlctrl The new codepen is not suitable to reproduce the issue. The "irrelevant code" had a purpose.

We are talking about a race condition. The bug only appears if your view reaches a certain size and thus vue needs more time to rerender it. Only then vue-router executes the .push(...) _while_ vue is still not done and produces the crash. See the "What is actually happening?" section. I wrote it based on debugging the internal code.

Please reopen the issue. IMHO it is a major flaw of the interoperability of both libraries.

It's not really a race condition, because even if you make the timeout 1000ms the same error still happens (even before the timer fires).

In fact it's another vdom patching related bug which has been fixed in Vue.js core (will be out in rc.4)

Makes sense to me. Thank you @yyx990803 !

@analog-nico Sorry for the close!

@fnlctrl No problem! Weeding out the usage issues is important to keep the workload manageable. Especially for a project with this much attention. Btw, I am happy to see that you are part of a healthy core maintainer group of the library I so much love and depend on. Thank you!

Thanks! I just verified it with [email protected] and [email protected] and it works.

Was this page helpful?
0 / 5 - 0 ratings