ChatGPT解决这个技术问题 Extra ChatGPT

什么是 nextTick 以及它在 Vue.js 中的作用?

我阅读了the docs,但我仍然无法理解。

我知道 datacomputedwatchmethods 的作用,但 Vue.js 中的 nextTick() 是做什么用的?

要理解的关键概念是 DOM 是异步更新的。当您在 Vue 中更改值时,更改不会立即呈现到 DOM。相反,Vue 将 DOM 更新排队,然后在计时器上更新 DOM。通常,这发生得很快,以至于没有什么区别,但是有时,您需要在 Vue 渲染后更新渲染的 DOM,您不能立即在方法中执行此操作,因为更新尚未发生然而。在这些情况下,您将使用 nextTickDocumented here
补充上面 https://stackoverflow.com/q/47634258/9979046 中@Bert 所说的内容,nextTick() 将用于单元测试中,当您需要检查 DOM (HTML) 中是否存在元素时,例如,如果您获得有关 Axios 请求的一些信息。
为什么我觉得 nextTick 类似于 const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };

t
tony19

一切都与时间有关

nextTick 允许您在更改某些数据之后执行代码,并且 Vue.js 已根据您的数据更改更新虚拟 DOM,但 之前浏览器已呈现该页面上的变化。

通常,devs use the native JavaScript function setTimeout 可以实现类似的行为,但使用 setTimeout 会将控制权交给浏览器之前,它会将控制权交还给您(通过调用您的回调)。

例子

假设您更改了一些数据; Vue 然后根据该数据更改更新 vDOM(更改尚未由浏览器呈现到屏幕上)。

如果此时您使用 nextTick,您的回调将立即被调用,并且浏览器将在该回调完成执行后更新页面。

如果您改为使用 setTimeout,则浏览器将有机会更新页面,然后您的回调将被调用。

您可以通过创建如下所示的小组件来可视化此行为:
(检查 this fiddle 以实时查看)

<template>
  <div class="hello">
    {{ msg }}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
        msg: 'One'
    }
  },
  mounted() {
      this.msg = 'Two';

      this.$nextTick(() => {
          this.msg = 'Three';
      });
  }
}
</script>

运行本地服务器。您将看到正在显示的消息“三”。

现在,将 this.$nextTick 替换为 setTimeout

setTimeout(() => {
    this.msg = 'Three';
}, 0);

重新加载浏览器。在看到“三”之前,您将看到“二”。

这是因为,使用 setTimeout

Vue 将 vDOM 更新为“二” Vue 将控制权交给了浏览器 浏览器显示“二” 回调被调用 Vue 将 vDOM 更新为“三” Vue 将控制权交给了浏览器 浏览器显示“三”

但是使用 nextTick,我们跳过了第 2 步和第 3 步! Vue 不会在第一次 vDOM 更新后传递控制权,而是调用回调立即,这会阻止浏览器更新,直到回调完成。在此示例中,这意味着从未实际显示“二”。

要了解 Vue 如何实现这一点,您需要了解 JavaScript Event Loopmicrotasks 的概念。

一旦您清楚(呃)这些概念,请检查 source code for nextTick


这个答案让我非常清楚如何以及何时使用 nexttick 以及何时使用 setTimeOut。谢谢你
t
tony19

Next Tick 基本上允许您在对反应性属性(数据)进行一些更改后,在 vue 重新渲染组件之后运行一些代码。

// modify data
vm.msg = 'Hello'
// DOM not updated yet
Vue.nextTick(function () {
   // this function is called when vue has re-rendered the component.
})
    
// usage as a promise (2.1.0+, see note below)
Vue.nextTick()
   .then(function () {
       // this function is called when vue has re-rendered the component.
    })

来自 Vue.js 文档:

推迟在下一个 DOM 更新周期后执行的回调。在您更改一些数据以等待 DOM 更新后立即使用它。

阅读有关它的更多信息,here


怎么更新?这是我不明白的。如果我更新 vm.msg 则 dom 已经更新,因为有一个新文本 ''hello" .. 那么我该如何再次更新它?你能发布一个带有示例的小提琴吗?谢谢
好的,我将编辑答案,并尝试进一步解释。
@hidar,您可以在必须进行多次更新的情况下使用它,但您希望在不同的 dom 周期中显式地相互渲染
这不是为了让您更新 DOM 本身,而是在它受到 Vue 所做更改的影响/修改后对其进行任何操作(更新、从中读取信息等)(因为您更改了响应式属性值, ETC)。
这是一个让它变得更简单的例子。
n
nos nart

为了使 Pranshat 对使用 nextTicksetTimeout 之间区别的回答更加明确,我分叉了他的小提琴:here

mounted() {    
  this.one = "One";
     
  setTimeout(() => {
    this.two = "Two"
  }, 0);
      
  //this.$nextTick(()=>{
  //  this.two = "Two"
  //})}
}

您可以在小提琴中看到,使用 setTimeOut 时,一旦组件在适应更改之前安装,初始数据会非常短暂地闪烁。然而,当使用 nextTick 时,数据在呈现给浏览器之前被劫持、更改。因此,浏览器显示更新的数据,甚至不知道旧数据。希望一举清除这两个概念。


D
Dileep Pal

我已经创建了一个有用的演示,在什么情况下我们可以在 Vuejs 中使用 nextTick,如果您想在 DOM 更新后立即更新或运行某些东西,请参阅 addMessage 函数,我正在调用另一个函数,其中我正在使用 nextTick 函数更新滚动到查看最新消息。

CDN VUE 3

  • {{msg}}