Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Vue to update the actual DOM right away when nextTick doesn't work, from a .vue file?

When I have a Vue component in a .vue file with a data member isLoading: false, and a template:

<div v-show="isLoading" id="hey" ref="hey">Loading...</div>
<button @click="loadIt()">Load it</button>

And a method:

loadIt() {
  this.isLoading = true
  this.$nextTick(() => {
    console.log(this.$refs.hey)                  // virtual DOM
    console.log(document.getElementById('hey'))  // actual DOM
    // ...other work here
  })
}

I thought that the nextTick function would allow both the virtual and real DOM to update, and thus the two console.log lines would output the same results. However, they do not: it seems that the real DOM isn't being updated right away, and thus the second log results in a element with display: none; whereas the first log doesn't--I get this on the console:

<div id="hey" data-v-964d645e="" style="">
<div id="hey" data-v-964d645e="" style="display: none;">

(By the way, even if I use setTimeout instead of this.$nextTick, I get the very same results from console.log. I also tried using the updated hook, but the same symptoms happen there. If I code any variation in a .js file, the problem goes away, but it persists when in a .vue file.)

Is there some kind of optimization or further asynchrony in how Vue updates the actual DOM from the virtual DOM? How do I get the actual DOM to update right away?

like image 557
Patrick Szalapski Avatar asked Sep 07 '25 11:09

Patrick Szalapski


1 Answers

This works pretty much as expected, with messages matching both before and after DOM update.

I think your understanding that the refs call returns a virtual node rather than an actual DOM element is incorrect.

new Vue({
  el: '#app',
  data: {
    isLoading: false
  },
  methods: {
    loadIt() {
      this.isLoading = true;
      this.tellMeAboutIt('before');
      this.$nextTick(() => this.tellMeAboutIt('after'));
    },
    tellMeAboutIt(when) {
        console.log(`Virtual ${when}:`, this.$refs.hey) // virtual DOM
        console.log(`Actual ${when}:`, document.getElementById('hey')) // actual DOM
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div v-show="isLoading" id="hey" ref="hey">Loading...</div>
  <button @click="loadIt()">Load it</button>
</div>
like image 134
Roy J Avatar answered Sep 09 '25 01:09

Roy J