$nextTick explanation that you can understand at a glance

$nextTick explanation that you can understand at a glance

1. Functional description

Today we are going to implement this small function; after the page is rendered, a div element is displayed; when this div element is clicked, the div element disappears; an input element appears; and the input element is focused. I believe everyone thinks it is simple, let's take a look~

Create a component named NextTick.vue;

Introducing registration in the page

2. Parent component

<template>
  <div>
    <next-tick></next-tick>
  </div>
</template>

<script lang="ts">
import NextTick from "../components/NextTick.vue"
export default {
  name:"About",
  components:{
    NextTick
  },
}
</script>

3. Subcomponent NextTick.vue

<template>
    <div>
        <div>I am a component</div>
        <div v-if="flag" class="sun" @click="handerClick">Show input</div>
        <input v-else ref="inputRef" class="yuelaing"/>
    </div>
</template>
<script>
export default {
    data(){
        return {
            flag:true,
        }
    },
    methods: {
        handerClick(){
            this.flag=false;
            this.$refs.inputRef.focus();
        },
    },
}
</script>

4Why is it undefined?

this.flag=false;
this.$refs.inputRef.focus();

When executing page operations, this.$refs.inputRef.focus();

It takes time (it has not been refreshed yet; it is still an old page)

The DOM element has not been obtained at this time.

So it will report an error.

Solution 1:

So just let the page get the element; use setTimeout

setTimeout(()=>{
      this.$refs.inputRef.focus();
},100)

It is possible to deal with this problem in this way;

But it seems very unprofessional;

Solution 2:

//When the component is re-rendered on the view according to the latest data, the function this.$nextTick(()=>{
    this.$refs.inputRef.focus();
})

5. Can changing v-if to v-show get the focus?

Some people say: Because v-if is dynamically created and destroyed; the process of creation and destruction takes time! That is why v-if cannot get the element node, which can be avoided by using v-show.

Do you think what you said makes some sense?

Let's try replacing v-if with v-show

<template>
    <div>
        <div>I am a component</div>
        <div v-show="flag" class="sun" @click="handerClick">Show input</div>
        <input v-show="!flag" ref="inputRef" class="yuelaing"/>
    </div>
</template>
<script>
export default {
    data(){
        return {
            flag:true,
        }
    },
    methods: {
        handerClick(){
            this.flag=false;
            console.log( this.$refs.inputRef );
            this.$refs.inputRef.focus();
        },
    },
}
</script>

6. Actual Results

We found that although the page did not report an error, it was not focused; changing to v-show obviously did not solve this problem

The reason for this problem is that after this.flag=false in the child component, the following code is executed immediately

this.$refs.inputRef.focus();

However, when executing, the view has not been refreshed yet; it is still the old page, and the DOM element cannot be obtained at this time, so undefined appears; that is why we can focus after adding a delay;

When the component is re-rendered on the view based on the latest data, the function inside is executed

This is the basic usage of $nextTick

this.$nextTick(()=>{
    this.$refs.inputRef.focus();
})

7. Can I get the focus by turning a component into a page?

Others say: Because it is a child component, the child component is rendered after the parent component. So no element node was obtained.

This is also the reason...

I feel like what the previous friend said is not right, in order to solve the doubts. We decided to turn the subcomponent into a page and see

<template>
  <div>
    <div>I am a component</div>
    <div v-show="flag" class="sun" @click="handerClick">Show input</div>
    <input v-show="!flag" ref="inputRef" class="yuelaing"/>
  </div>
</template>
<script>
export default {
  data(){
    return {
        flag:true,
    }
  },
  methods: {
      handerClick(){
        this.flag=false;
        this.$refs.inputRef.focus();
      },
  },
}
</script>

We found that it still doesn't work; this fully illustrates that after updating the data, Vue is not updated in real time.

There is a time difference between data being updated and displayed on the page. If we call the page data within the time difference, we will not be able to obtain it.

In other words: Vue executes asynchronously when updating the DOM

8. Why is there $nextTick

The reason for $nextTick is that after the data in Vue changes, the DOM on the view will not be updated immediately; it takes time to update the DOM

Let's take a look at this through a small experiment

<template>
  <div>
    <div ref="unique">
      <h1>{{ cont }}</h1>
    </div>
    <div class="sun" @click="handerClick">Change value</div>
  </div>
</template>
<script>
export default {
  data(){
    return {
      cont:'I am the default value'
    }
  },
  methods: {
      handerClick(){
        this.cont = 'I changed the default value';
        console.log('1==>',this.$refs.unique.innerText);
        this.$nextTick(()=>{
          console.log('2==>',this.$refs.unique.innerText);
        })
      },
  },
}
</script>

We found that the first value and the second value are different, because the update of DOM on the view needs to be in between. We get the element value within this difference, and it is still the old value. So the first value is the initial value, and the second value is the changed value.

Since we hope to update the data, we can still get the value on the DOM immediately

So vue provides $nextTick to solve this problem

9. Difference between Vue.nextTick and this.$nextTick

Vue.nextTick is a global method

this.$nextTick( [callback] ) is an instance method.

We all know that a page can have multiple instances, which means that this.$nextTick can be accurate to a certain instance. In fact, the two are essentially the same.
The only difference is that one is global and the other is precise to a specific instance. The accuracy is different.

10. A little trick for using nextTick

We all know that when the lifecycle mounted is rendered, it cannot be 100% guaranteed that all subcomponents can be rendered, so we can use this.$nextTick in mounted to ensure that all subcomponents can be rendered.

The mounted hook is not called during server-side rendering.

mounted: function () {
  this.$nextTick(function () {
    //When the data changes,
    //After re-rendering on the view, execute the method inside //This sentence is equivalent to:
   // Delay the callback until the next DOM update cycle // Equivalent to: after modifying the data, then waiting for the DOM to update before executing })
}

Summarize

This is the end of this article about $nextTick. For more information about $nextTick, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Explanation of the usage of $nextTick in Vue
  • Function and usage of this.$nextTick in Vue
  • Vue2.0$nextTick listens for the callback function method after data rendering is completed
  • Detailed explanation of how Vue + Vuex uses vm.$nextTick
  • Detailed explanation of the usage of $nextTick and $forceUpdate in Vue
  • VUE updates DOM asynchronously - using $nextTick to solve DOM view problems
  • Detailed explanation of the differences between vue directives and $nextTick in manipulating DOM
  • A comprehensive analysis of $nextTick in Vue

<<:  Tutorial on customizing rpm packages and building yum repositories for Centos

>>:  You may not know these things about Mysql auto-increment id

Recommend

Difference between src and href attributes

There is a difference between src and href, and t...

jQuery realizes image highlighting

It is very common to highlight images on a page. ...

Solve nginx "504 Gateway Time-out" error

Students who make websites often find that some n...

Implementing a web player with JavaScript

Today I will share with you how to write a player...

Getting started with JavaScript basics

Table of contents 1. Where to write JavaScript 2....

Solution to nginx hiding version number and WEB server information

Nginx can not only hide version information, but ...

Detailed explanation of several examples of insert and batch statements in MySQL

Table of contents Preface 1.insert ignore into 2....

The difference between Vue interpolation expression and v-text directive

Table of contents 1. Use plugin expressions 2. Us...

How to use IDEA to configure tomcat and create JSP files

Before using idea to write JSP files, you need to...

JS implements circular progress bar drag and slide

This article example shares the specific code of ...

Example code of CSS layout at both ends (using parent's negative margin)

Recently, during the development process, I encou...

Use the more, less, and cat commands in Linux to view file contents

In Linux, the commands cat, more, and less can al...

Several common methods of sending requests using axios in React

Table of contents Install and introduce axios dep...