浅谈浅谈 $nextTick

151 阅读1分钟

概述

$nextTick是vue的实例方法,它是一个用于DOM更新完成后执行回调函数的方法。

此处需要理解vue的数据更新是一个异步任务,所以vue修改数据后,页面无法立刻更新,而是放到一个任务队列,并且缓存同一轮事件循环中所有的数据改变。如果同一个watcher被多次触发,只会推入到队列中1次。在缓冲时去除重复的操作,下一轮事件循环时,才开始更新。

此刻DOM操作获取的数据还是还是未更新的数据,而$nextTick可以监听DOM更新完成,再执行回调函数,确保拿到更新完成后的数据或者确定更新完成后再进行其他的的操作。

应用场景

created阶段的DOM操作 例如:获取改变后的数据,或者DOM页面改变后要进行的操作。 以下有两个案例帮助理解。

语法

this.$nextTick(回调函数)

注意:

this.$nextTick()返回的是一个promise对象; 支持async/await

案例

☛ one ☚ 目标:点击按钮一次,控制台打印出1

<template>
  <div>
    <p>vue更新DOM是异步的</p>
    <p ref="myP">{{ count }}</p>
    <button @click="btn()">点击count+1,马上提取p标签内容</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods:{
    btn(){
        this.count++
        // console.log(this.$refs.myP.innerHTML);//0   此代码在视图更新之前执行了所以最先拿不到1
        //通过nextTick() 去让这个方法中的代码在页面dom更新完成之后再执行
        this.$nextTick(()=>{
            console.log(this.$refs.myP.innerHTML);//1
        })
    }
  }
};
</script>

<style></style>

☛ two ☚

目标:实现点击按钮,输入框显示马上能够聚焦

  <div>
    <h2>$nextTick说明</h2>
    <input type="text" placeholder="请输入关键词" v-if="isShow" ref="foc" />
    <button v-else @click="btn()">点击我搜索</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShow: false,
    };
  },
  methods: {
    btn() {
      //点击按钮  输入框显示,按钮隐藏 用到v-if v-else(互斥)
      this.isShow = true;
      this.$nextTick(() => {
        //让input框渲染完成以后 再执行focus事件
        //$refs 可以代替document.querySelector拿到DOM元素
        //还可以调用DOM元素的属性和方法
        this.$refs.foc.focus();
      });
    },
  },
};
</script>

<style></style>

注意:此处如果不使用nextTick是无法立刻实现聚焦功能的,当然还可以使用setTimeout()的方法同样可以达到效果,不过此方式不够专业。依次可推,nextTick是无法立刻实现聚焦功能的,当然还可以使用setTimeout()的方法同样可以达到效果,不过此方式不够专业。 依次可推,nextTick的原理 相当于设置了一个延时,一定会等待页面DOM渲染完成后才执行回调函数。