当我在.vue文件中有一个带有数据成员 isLoading: false
和模板的Vue组件时:
<div v-show="isLoading" id="hey" ref="hey">Loading...</div>
<button @click="loadIt()">Load it</button>
一个方法:
loadIt() {
this.isLoading = true
this.$nextTick(() => {
console.log(this.$refs.hey) // virtual DOM
console.log(document.getElementById('hey')) // actual DOM
// ...other work here
})
}
我认为nextTick函数将允许虚拟和真实DOM更新,因此两个console.log行将输出相同的结果 . 但是,他们没有:似乎真正的DOM没有立即更新,因此第二个日志导致一个元素 display: none;
而第一个日志没有 - 我在控制台上得到这个:
<div id="hey" data-v-964d645e="" style="">
<div id="hey" data-v-964d645e="" style="display: none;">
(顺便说一句,即使我使用 setTimeout
而不是 this.$nextTick
,我从console.log获得了相同的结果 . 我也尝试使用 updated
钩子,但是同样的症状发生在那里 . 如果我在.js文件中编码任何变体,问题消失了,但在.vue文件中它仍然存在 . )
在Vue如何从虚拟DOM中更新实际DOM时,是否存在某种优化或进一步的异步? How do I get the actual DOM to update right away?
3 回答
这非常符合预期,消息在DOM更新之前和之后都匹配 .
我认为你理解refs调用返回虚拟节点而不是实际的DOM元素是不正确的 .
事实证明,eslint-loader缓存或babel-loader缓存的问题导致了这种奇怪 . 我只能通过删除所有
node_modules\.cache
来修复它 . 太糟糕了我不知道为什么它发生在一开始 .请查看文档中的Vue lifecycle . 值得注意的是,这两个事件之间存在脱节 . 另请注意,
nextTick()
等待下一个DOM更新周期,不一定是虚拟DOM .这通常通过使用
updated
生命周期钩子来解决,该钩子在虚拟DOM已经更新之后执行代码 . 如果您需要执行一些代码并保证虚拟DOM已经更新,那么您将需要在那里执行 .您可能也对reactivity in depth感兴趣 . 这应该是生命周期图的良好补充 .