$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

Introduction to the use of HTML element noscript

noscript definition and usage The noscript elemen...

CSS3 border effects

What is CSS# CSS (abbreviation of Cascading Style...

Detailed explanation of the core concepts and basic usage of Vuex

Table of contents introduce start Install ① Direc...

The pitfalls encountered when learning Vue.js

Table of contents Class void pointing ES6 Arrow F...

Implementation code for adding slash to Vue element header

<template> <div class="app-containe...

Do you know the meaning of special symbols in URL?

1.# # represents a location in a web page. The ch...

Detailed explanation of various join summaries of SQL

SQL Left Join, Right Join, Inner Join, and Natura...

Three properties of javascript objects

Table of contents 1. writable: writable 2. enumer...

Explain TypeScript mapped types and better literal type inference

Table of contents Overview Using mapped types to ...

Docker packages the local image and restores it to other machines

1. Use docker images to view all the image files ...

Use of Linux passwd command

1. Command Introduction The passwd command is use...

CSS3 Bezier Curve Example: Creating Link Hover Animation Effects

We will use CSS3 animated transitions to create a...

How to create Baidu dead link file

There are two types of dead link formats defined b...

The problem of form elements and prompt text not being aligned

Recent projects involve the creation of a lot of ...