$nextTick VS setTimeout,看看它们的差异


本文摘自PHP中文网,作者青灯夜游,侵删。

本篇文章给大家简单对比一下$nextTick 与 setTimeout,看看它们之间有什么差异。

一个前端开发人员(小智)走进了一个Vue酒吧。小智点了他最喜欢的鸡尾酒:Nuxt。酒保正在努力制作中。然后他自己就唠叨了起来。

小智讲述了他是如何在Vue 3的实例方法下发现$nextTick的,并大吃一惊。小智使用Vue已经有一段时间了,他已经习惯了把$watch$emit写成实例方法。那么,$nextTick是用来做什么的?Vue文档说,它"[defers]回调,在下一个DOM更新周期后执行"。

但是小智并不相信。

他继续讲述他是如何尝试这样做的:

1

2

3

4

this.loadingAnimation = true

this.startVeryLongCalculation()

this.completeVeryLongCalculation()

this.loadingAnimation = false

有用。 为什么?

nextTick做什么?

nextTick接受一个延迟到下一个DOM更新周期的回调函数。这只是Vue的一种说法,"嘿,如果你想在DOM更新后执行一个函数(这种情况很少发生),我希望你使用nextTick而不是setTimeout"。

1

Vue.nextTick(() => {}) // syntax

下面很快就会讲到setTimeoutnextTick参数。我们用这个例子来可视化nextTick的行为:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<template>

  <div>

    {{ currentTime }}

  </div>

</template>

 

<script>

export default {

  name: 'getCurrentTime',

  data() {

    return {

      currentTime: ''

    }

  },

  mounted() {

    this.currentTime = 3;

 

    this.$nextTick(() => {

        let date = new Date()

        this.currentTime = date.getFullYear()

    });

  }

}

</script>

在J电脑上运行这个代码片段。它将显示2021年。并不是说如果你去掉nextTick,就不会得到同样的结果。然而,你应该明白,Vue会根据数据中的内容对DOM进行修改。

在上面的代码片段中,Vue将DOM更新为3,然后调用回调,将DOM更新为2021,最后将控制权交给浏览器,浏览器将显示2021

到目前为止,我们已经研究了nextTick在回调队列中插入回调函数并在适当的时候执行该函数。

这个你可能会感兴趣,nextTick中的回调是作为事件循环中的一个微任务使用的。nextTick的源代码明确指出,"nextTick行为利用了微任务队列,可以通过本地的Promise.thenMutationObserver来访问。"

setTimeout vs nextTick

在DOM更新后执行函数的另一种方法是使用JavaScript的setTimeout()函数。

我们将上面的代码用setTimeout替换nextTick:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<template>

  <div>

    {{ currentTime }}

  </div>

</template>

 

<script>

export default {

  name: 'getCurrentTime',

  data() {

    return {

      currentTime: ''

    }

  },

  mounted() {

    this.currentTime = 3;

 

    setTimeout(() => {

      let date = new Date()

      this.currentTime = date.getFullYear()

    }, 0);

  }

}

</script>

运行此代码片段。 首先看到3然后2021。它发生得很快,因此如果没有看到此行为,需要刷新浏览器。

在上面的代码片段中,Vue将DOM更新为3,并提供浏览器控制。然后浏览器显示3,调用回调函数,将DOM更新到2021,最后将控制权交给浏览器,现在浏览器显示2021

nextTick的实现在不支持PromiseMutationObserver的浏览器(IE 6-10和Opera Mini浏览器)上,使用setTimeout作为后备方法,对于不支持PromiseMutationObserver的浏览器(IE 10),它更倾向于setImmediate

何时使用 nexttick

  • 当你想使用setTimeout
  • 当你想确定DOM能反映你的数据时
  • 在尝试执行异步操作时,遇到Uncaught (in promise) DOMException等错误。记住,Vue是异步更新DOM的

最后来个示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<div id="app">

  <div ref="listScroll" class="scrolledList">

    <ul ref="scrolledHeight">

      <li v-for="month in months">

        {{month}}

      </li>              

    </ul>

  </div>

 

  <input type="text" placeholder="Add Month" v-model="month">

  <button @click="addMessage" @keyup.enter="addMessage"> Add Month</button>

</div>

 

<script src="https://unpkg.com/vue@next">

  Vue.createApp({

    data() {

      return {

        month: '',

        months: ['Jan', 'Feb', 'Apr', 'May', 'June', 'July', 'Aug']

      }

    },

    mounted() {

      this.updateScrollNextTick()

    },

    methods: {

      addMessage() {

        if(this.month == ''){

          return

        }

 

        this.months.push(this.month)

        this.month = ''

        this.updateScrollNextTick()

      },

      updateScrollNextTick () {

        let scrolledHeight = this.$refs.scrolledHeight.clientHeight

 

        this.$nextTick(() => {

          this.$refs.listScroll.scrollTo({

            behavior: 'smooth',

            top: scrolledHeight

          })

        })

      }

    },

  })

  .mount("#app")

</script>

示例地址:https://codepen.io/ammezie/pen/OJpOvQE

主要部分:

1.png

运行结果:

2.gif

在上面的代码片断中,我们想在一个新项目被添加到列表中时获得平滑的向下滚动效果。浏览一下代码,尝试修改一下,去掉nextTick,你就会失去那种平滑的滚动效果。你也可以尝试用setTimeout来代替nextTick

总结

在本文中,我们探索了nextTick是如何工作的。我们进一步了解了它与普通的JavaScript setTimeout的不同之处,并介绍了实际的用例。

英文原文地址:https://blog.logrocket.com/understanding-nexttick-in-vue-js/

作者:Chimezie Enyinnaya

译者:前端小智

转载地址:https://segmentfault.com/a/1190000040246186

更多编程相关知识,请访问:编程入门!!

以上就是$nextTick VS setTimeout,看看它们的差异的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

vue和react属于js库吗

vue和react状态管理有啥区别?

click在vue里怎么实现

vue中怎么导出excel文件?

vue兄弟组件传值有哪五种方法

vue中让子组件修改父组件数据的方法

vue项目中怎么设置title图标?(图文详解)

vue-cli+express获取mongodb数据的方法介绍

vue.js组件化是什么意思

vue路由守卫有哪三种类型

更多相关阅读请进入《vue》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...