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?
this.$refs.hey.getAttribute("style")
for an accurate snapshot. Does not negate your issue, though. – Richard Matsenthis.$refs.hey
is not a virtual DOM element; it's an actual DOM element – Stephen Thomas