mount() 挂钩中的 Vue $nextTick 无法按预期工作
Posted
技术标签:
【中文标题】mount() 挂钩中的 Vue $nextTick 无法按预期工作【英文标题】:Vue $nextTick in mounted() hook doesn't work as expected 【发布时间】:2021-11-03 00:40:39 【问题描述】:我正在尝试对挂载钩子中的元素应用一些内联样式,作为过渡的起点。
mounted()
this.styles =
backgroundColor: 'silver'
;
在那之后,在下一个刻度上,我想添加一组新样式,并让过渡发生
this.$nextTick(() =>
this.styles =
backgroundColor: 'gold'
);
这并不像我期望的那样工作,它会立即使用第二种样式呈现元素。
如果我将$nextTick
替换为setTimeout
,它将按预期工作。
我哪里错了?必须有一种方法可以在不依赖超时的情况下实现这一点。
I've recreated the problem here
PS 我知道我可以用 Vue 过渡来做到这一点,但在实际项目中,要应用的样式更复杂并且是通过程序计算的,所以我宁愿在 js 中做,而不是在 css 中做
【问题讨论】:
你说过它可以使用setTimeout
。在您的示例中,我可以看到您确实在超时中等待了 100 毫秒。 $nextTick
最后比那个短。我知道这不是您所期望的,但这就是它的工作原理。
setTimeout(() => this.styles = backgroundColor: 'pink' , 0);你可以用 0 时间做 Timeout 以获得你想要的效果。应该和nextTick一样,因为某些原因不起作用。
正如我已经回答的那样,您需要等待下一个event loop
。 $nextTick
不这样做????
【参考方案1】:
你说过它可以使用setTimeout
。在您的示例中,我可以看到您确实在超时中等待了 100 毫秒。 $nextTick
最后更短。它不会等待下一个event loop
。
我知道这不是您所期望的,但这就是它的工作方式。您需要等待另一个event loop
。即使将timeout
与0
一起使用也可以解决问题。
setTimeout(() =>
this.styles =
backgroundColor: 'pink'
, 0);
【讨论】:
嗯。你是对的,它确实适用于超时0
。我猜docs 有点误导,对Use it immediately after you've changed some data to wait for the DOM update
说。实际上(如this 回答澄清)nextTick 发生在 Vue.js 更新虚拟 DOM 之后,但在浏览器在页面上呈现该更改之前。现在这就解释了被质疑的行为【参考方案2】:
在您的情况下,两次渲染之间几乎没有延迟。
要查看silver
将如何变成gold
,您可以致电setTimeout
:
this.$nextTick(() =>
setTimeout(() =>
this.styles =
backgroundColor: 'gold'
, 1000)
);
我不确定您是否应该将其用作现成的解决方案,因为使用 CSS 过渡效果更好。也许您不仅需要更改样式,还需要添加一些类以在样式计算完成后打开 CSS 过渡。
【讨论】:
就像我在问题中所说,当然,它适用于超时,但它绝对应该在没有它的情况下工作以上是关于mount() 挂钩中的 Vue $nextTick 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
用于从 Vue 组件中的 Firebase 检索数据的生命周期挂钩
@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property 'components' of undef