Exception thrown by Vue code during update with template involving v-if and css styles #4535

Closed
ericremoreynolds opened this Issue Dec 21, 2016 · 4 comments

Projects

None yet

3 participants

@ericremoreynolds
ericremoreynolds commented Dec 21, 2016 edited

Vue.js version

2.1.6

Reproduction Link

http://jsfiddle.net/od3m0ta9/

Steps to reproduce

Given the following code

<html>
  <body>
    <div id="vue">
      <div style="background: blue;" v-if="!message">Something</div>
      <div style="background: red;" v-if="message" v-text="message"></div>
      <button v-on:click="buttonClicked">Click me</button>
    </div>

    <script src="https://unpkg.com/vue@2.1.6/dist/vue.js"></script>

    <script>
    var vue = new Vue({
      el: '#vue',
      data: {
        message: null
      },
      methods: {
        buttonClicked: function() {
          this.message = "Hello @ " + new Date();
        }
      }
    });
    </script>
  </body>
</html>

clicking the button causes the following exception to be thrown in the Chrome Version 55.0.2883.95 (64-bit) console

DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
    at Object.removeChild (https://unpkg.com/vue@2.1.6/dist/vue.js:3825:8)
    at removeVnodes (https://unpkg.com/vue@2.1.6/dist/vue.js:4188:19)
    at patchVnode (https://unpkg.com/vue@2.1.6/dist/vue.js:4333:9)
    at updateChildren (https://unpkg.com/vue@2.1.6/dist/vue.js:4252:9)
    at patchVnode (https://unpkg.com/vue@2.1.6/dist/vue.js:4328:29)
    at Vue$3.patch [as __patch__] (https://unpkg.com/vue@2.1.6/dist/vue.js:4451:9)
    at Vue$3.Vue._update (https://unpkg.com/vue@2.1.6/dist/vue.js:2224:19)
    at Vue$3.<anonymous> (https://unpkg.com/vue@2.1.6/dist/vue.js:2191:10)
    at Watcher.get (https://unpkg.com/vue@2.1.6/dist/vue.js:1656:27)
    at Watcher.run (https://unpkg.com/vue@2.1.6/dist/vue.js:1725:22)

and all JS execution stops (this is proven by the fact the time does not update with repeated clicks).

Notes

Strangely, the error doesn't happen if you drop the style attributes from the two divs.

Salutation

Thanks! Best regards,

Eric

@ericremoreynolds

I found a workaround in the meantime. Wrap each of the two divs in a dummy div with no attributes, i.e. substitute the relevant lines with this:

<div><div style="background: blue;" v-if="!message">Something</div></div>
<div><div style="background: red;" v-if="message" v-text="message"></div></div>
@LinusBorg
Member

Thanks for reporting this. It seems that Vue tries to re-use the div element instead of removing one and adding the other (Re-using elements is generally preferred for performance reasons), but messes up in the process.

Seems to be a bug indeed.

A better workaround would be to explicitly key the elements with a key (unique in the component's scope) to force Vue to actually replace the divs:

http://jsfiddle.net/Linusborg/od3m0ta9/2/

@LinusBorg LinusBorg added 2.1 bug labels Dec 21, 2016
@ericremoreynolds

Cool thanks for the better workaround

@defcc
Member
defcc commented Dec 22, 2016

Thanks, I am looking into it.

@defcc defcc self-assigned this Dec 22, 2016
@yyx990803 yyx990803 closed this in #4548 Dec 23, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment