什么是nextTick或它在VueJs中做了什么

hid*_*dar 61 vue.js vuejs2

我阅读了文档,但我无法理解.我知道什么数据,计算,观察,方法做什么,但nextTick()在vuejs中使用什么?

Pra*_*ant 93

nextTick允许您在更改数据后执行某些操作,并且VueJS已根据您的数据更改更新DOM,但在浏览器在页面上呈现更改后更新.

通常,开发人员使用本机JavaScript函数setTimeout来实现类似的行为.但是,setTimeout在通过回调将控制权交给您之前,使用放弃对浏览器的控制.

比方说,你改变了一些数据.Vue根据数据更新DOM.请注意,浏览器尚未将DOM更改呈现给屏幕.如果您使用nextTick,则立即调用您的回调.然后,浏览器更新页面.如果你使用过setTimeout,你的回调只会被调用.

您可以通过创建如下所示的小组件来可视化此行为:

<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>
Run Code Online (Sandbox Code Playgroud)

运行本地服务器.您将看到Three正在显示的消息.

现在,您的替换this.$nextTicksetTimeout

setTimeout(() => {
    this.msg = 'Three';
}, 0);
Run Code Online (Sandbox Code Playgroud)

重新加载浏览器.你会看到Two,你看之前Three.

检查这个小提琴,看看它是否活着

那是因为,Vue更新了DOM Two,控制了浏览器.浏览器显示Two.然后,调用你的回调.Vue将DOM更新为Three.哪个浏览器再次显示.

随着nextTick.Vue udpated DOM到Two.叫你的回调.Vue将DOM更新为Three.然后控制浏览器.并且,浏览器显示Three.

希望很清楚.

要了解Vue如何实现这一点,您需要了解Event Loop微任务的概念.

一旦你明确了这些概念(呃),检查nextTick源代码.

  • 我不明白的一件事是,当你说"vue更新数据"时,你是指引用更新的ex:`this.name ='foo'`或者你是指在页面中注入html元素? (4认同)
  • 这个答案让我非常清楚地了解如何以及何时使用 nexttick 以及何时使用 setTimeOut。谢谢 (2认同)

Dak*_*ani 12

下一个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.
})
Run Code Online (Sandbox Code Playgroud)

从Vue.js文档:

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

在这里阅读更多相关信息.

  • 更新它怎么样?这是我不承担的.如果我更新vm.msg然后dom已经更新,因为有一个新文本''你好'..所以我怎么能再次更新它?你可以发一个小提琴示例吗?谢谢 (2认同)

Hum*_*mad 8

Vue文档说:

Vue.nextTick([回调,上下文])

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

嗯...,如果刚开始觉得很吓人,请不要担心,我会尽力解释得尽可能简单。但是首先,您应该知道两件事:

  1. 它的用法并不常见。就像其中的一张银色魔术卡一样。我已经编写了几个Vue应用程序,并且一次或两次遇到了nextTick()。

  2. 一旦您看到了一些实际的用例,就更容易理解。有了这个主意,恐惧就会消失,并且您将拥有一个方便的工具。

那我们去吧。

了解$ nextTick

我们是程序员,不是吗?我们将使用我们钟爱的分而治之方法来尝试.nextTick()一点一点地翻译描述。它开始于:

推迟回调

好的,现在我们知道它接受了回调。所以看起来像这样:

Vue.nextTick(function () {
  // do something cool
});
Run Code Online (Sandbox Code Playgroud)

大。此回调被延迟(这就是千禧一代所说的延迟),直到…

下一个DOM更新周期。

好的。我们知道Vue异步执行DOM更新。它具有一种将这些更新“存储”到需要应用它们的方式。它创建更新队列,并在需要时刷新它。然后,“修补” DOM,并将其更新为最新版本。

什么?

让我再试一次:假设您的组件确实执行了一些必不可少的事情,并且很聪明,例如this.potatoAmount = 3.Vue不会自动重新渲染该组件(以及DOM)。它将排队所需的修改。然后,在下一个“滴答声”中(如在时钟中),刷新队列,并应用更新。多田!

好的!因此,我们知道可以nextTick()用来传递设置数据和DOM更新后立即执行的回调函数。

就像我之前说的那样。我不会提到的“数据流”方法可以驱动Vue,React和Google的另一种方法,这在大多数情况下都是不必要的。但是,有时我们需要等待某些元素在DOM中出现/消失/被修改。这是nextTick派上用场的时候。

更改一些数据以等待DOM更新后,请立即使用它。

究竟!这是Vue文档提供给我们的最后一个定义。在回调中,DOM已更新,因此我们可以与它的“最新”版本进行交互。

证明给我看

好吧好吧。查看控制台,您将看到我们的数据值仅在nextTick的回调内更新:

Vue.nextTick(function () {
  // do something cool
});
Run Code Online (Sandbox Code Playgroud)
const example = Vue.component('example', {
  template: '<p>{{ message }}</p>',
  data: function () {
    return {
      message: 'not updated'
    }
  },
  mounted () {
    this.message = 'updated'

        console.log(
        'outside nextTick callback:', this.$el.textContent
    ) // => 'not updated'

    this.$nextTick(() => {
      console.log(
        'inside nextTick callback:', this.$el.textContent
      ) // => 'not updated'
    })
  }
})


new Vue({
  el: '#app',
    render: h => h(example)
})
Run Code Online (Sandbox Code Playgroud)

用例

让我们尝试为定义一些有用的用例nextTick

想象一下,在安装组件时需要执行一些操作。但!不仅是组件。您还需要等待,直到所有子级都已安装并在DOM中可用为止。该死的!我们安装的钩子不能保证整个组件树都能渲染。

如果我们只有一个工具可以等待下一个DOM更新周期…

哈哈

mounted() {
  this.$nextTick(() => {
    // The whole view is rendered, so I can safely access or query
    // the DOM. ¯\_(?)_/¯
  })
}
Run Code Online (Sandbox Code Playgroud)

简而言之

因此:这nextTick是在设置数据并更新DOM之后执行函数的一种简便方法。

您需要等待DOM,也许是因为您需要执行一些转换,还是需要等待外部库加载其内容?然后使用nextTick。

有些人还在其单元测试中使用nextTick,以确保数据已更新。这样,他们可以测试组件的“更新版本”。

Vue.nextTick()或vm。$ nextTick()吗?

不用担心 两者(几乎)相同。Vue.nextTick()指的是全局API方法,vm.$nextTick()而是实例方法。唯一的区别是vm.$nextTick不接受上下文作为第二个参数。它总是绑定到this(也称为实例本身)。

最后一点凉意

请注意,它nextTick返回Promise,因此我们可以充分利用async/await并改进示例:

async mounted () {
    this.message = 'updated'
    console.log(this.$el.textContent) // 'not updated'
    await this.$nextTick()
    console.log(this.$el.textContent) // 'updated'
}
Run Code Online (Sandbox Code Playgroud)

内容已从采取通过阿德里亚Fontcuberta


Wal*_*ale 5

为了使Pranshat的有关使用nextTick和setTimeout的,更加明确的区别答案,我已付出他的小提琴: 这里

mounted() {    
  this.one = "One";

  setTimeout(() => {
    this.two = "Two"
  }, 0);

  //this.$nextTick(()=>{
  //this.two = "Two"
  //})}
Run Code Online (Sandbox Code Playgroud)

您会在小提琴中看到,使用setTimeOut时,一旦安装组件,然后适应更改,初始数据就会非常短暂地闪烁。而使用nextTick时,数据被劫持,更改,然后呈现给浏览器。因此,浏览器甚至在不了解旧数据的情况下也显示了更新的数据。希望能一举解决两个概念。