[think] $nextTick vs. setTimeout!

Author: Chimezie Enyinnaya
Translator: front end Xiaozhi
Source: blog

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this bowl washing wisdom who is still washing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

A front-end developer (Xiaozhi) walks into a Vue bar. Xiao Zhi ordered his favorite cocktail: Nuxt. The bartender is working on it. Then he nagged himself.

Xiao Zhi described how he found $nextTick under the example method of Vue 3 and was surprised. Xiao Zhi
Vue has been used for some time, and he is used to writing $watch and $emit as instance methods. So, what is $nextTick for? The Vue document says that it "calls back [defers] and executes after the next DOM update cycle".

But Xiaozhi doesn't believe it.

He went on to describe how he tried to do so:

this.loadingAnimation = true
this.startVeryLongCalculation()
this.completeVeryLongCalculation()
this.loadingAnimation = false

Useful. Why?

What does nextTick do?

nextTick accepts a callback function that delays to the next DOM update cycle. This is just Vue's saying, "Hey, if you want to execute a function after DOM update (which rarely happens), I want you to use nextTick instead of setTimeout".

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

The setTimeout and nextTick parameters will be discussed shortly below. We use this example to visualize the behavior of nextTick:

<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>

Run this code snippet on J computer. It will show 2021. It's not that if you remove nextTick, you won't get the same result. However, you should understand that Vue will modify the DOM according to the content in the data.

In the above code snippet, Vue updates DOM to 3, then calls callback, updates DOM to 2021, finally gives control to browsers, and browsers will display 2021.

So far, we have studied nextTick inserting a callback function into the callback queue and executing it when appropriate.

You may be interested in this. The callback in nextTick is used as a micro task in the event loop. nextTick's source code It is clearly pointed out that "the nextTick behavior utilizes the micro task queue and can be accessed through the local Promise.then or MutationObserver."

setTimeout vs nextTick

Another way to execute functions after DOM updates is to use JavaScript's setTimeout() function.

We replace nextTick with setTimeout in the above code:

<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>

Run this code snippet. First see 3, then 2021. It happens quickly, so if you don't see this behavior, you need to refresh the browser.

In the code snippet above, Vue updates the DOM to 3 and provides browser control. Then the browser displays 3, calls the callback function to update the DOM to 2021, and finally gives control to the browser. Now the browser displays 2021.

The implementation of nextTick uses setTimeout as a backup method on browsers that do not support Promise and MutationObserver (IE 6-10 and Opera Mini browsers). For browsers that do not support Promise and MutationObserver (IE 10), it prefers setImmediate.

When to use nexttick

  • When you want to use setTimeout
  • When you want to make sure that the DOM reflects your data
  • An error such as Uncaught (in promise) DOMException was encountered while trying to perform an asynchronous operation. Remember, Vue updates the DOM asynchronously

Finally, an example:

<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>

Example address: https://codepen.io/ammezie/pen/OJpOvQE

Main parts:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-oXrfxVSW-1626221844061)(/img/bVcS117)]

Operation results:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-zH0NCUvs-1626221844063)(/img/bVcS119)]

In the code snippet above, we want to get a smooth scroll down effect when a new item is added to the list. Browse the code, try to modify it, remove nextTick, and you will lose the smooth scrolling effect. You can also try using setTimeout instead of nextTick.

summary

In this article, we explored how nextTick works. We learned more about the differences between it and ordinary JavaScript setTimeout, and introduced the actual use cases.

~After that, I'm Xiaozhi. I'm going to educate a front-end little sister.

The possible bugs in editing cannot be known in real time. Afterwards, in order to solve these bugs, we spent a lot of time on log debugging. By the way, we recommend a useful bug monitoring tool Fundebug.

Original text: https://blog.logrocket.com/understanding-nexttick-in-vue-js/

communication

The article is continuously updated every week. You can search * * [Daqian world] on wechat to read it for the first time and reply to [welfare] * * there are many front-end videos waiting for you. This article GitHub https://github.com/qq449245884/xiaozhi Already included, welcome Star.

Keywords: Javascript Front-end Vue

Added by rid243 on Tue, 18 Jan 2022 04:18:32 +0200