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。即使将timeout0 一起使用也可以解决问题。

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

vue-test-utils:如何在 mount() 生命周期钩子(使用 vuex)中测试逻辑?

Vue $mount函数

vue.js 不会在mounted() 挂钩上更新

Vue的$mount做了啥