关于Vue 的nextTick相关知识

官方给的 Vue.nextTick 用法

在这里插入图片描述

关于Vue.nextTick 的疑惑

  • Vue.nextTick 是用来干嘛的
  • Vue.nextTick 是在什么时候用
  • Vue.nextTick 的原理是怎么样的
解释上面的问题
  • Vue.nextTick是用来更新vue的视图的。
  • Vue.nextTick在你的视图已经渲染了,需要再一次更新视图
  • Vue.nextTick 的原理分成两个 1,异步 2,事件循环
  • 1.异步解释
1.vue 视图更新解释

Vue 实现响应式并不是你想的那种,数据更新,视图就对应的更新了(dom)。而是按照vue自己制定的一些策略来进行视图(dom)更新

2.javascript 的运行机制问题理解 异步问题和同步问题

  2.1.javascript 的特点
      js 是单线程的运行 (具体单线程是什么自己百度一下) 单线程的机制就是说
      你在同一时间只能做一件事
      
  2.2 js的同步和异步问题差异
      同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
      异步任务:不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

具体来说异步运行机制:(下面一段百度复制的)

(1) 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。

任务队列是一个事件队列,主线程读取"任务队列",就是读取里面有哪些事件。

“任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列”,等待主线程读取。

回调函数
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

  • 事件循环
事件循环如字面意识就是循环执行事件(这里的事件是指调用任务队列的事件)

举例说明:一条流水线上(一个人) 同步任务就如同一件件物品,但是有的物品不合格或者其他原因,一个人处理不过来,第一次流水线循环的时候,这个不合格的物品因为没有时间执行,所以那个小本本记下来,等流水线上的执行完了,再回来看小本本上的那些事件(执行)

官方说法是这个样的:
事件循环:JS 会创建一个类似于 while (true) 的循环,每执行一次循环体的过程称之为 Tick。每次 Tick 的过程就是查看是否有待处理事件,如果有则取出相关事件及回调函数放入执行栈中由主线程执行。待处理的事件会存储在一个任务队列中,也就是每次 Tick 会查看任务队列中是否有需要执行的任务。

  • 主线程和任务队列的示意图(这张图是抄的不是自己画的)

在这里插入图片描述

Vue是怎么实现的这个功能的呢Vue.nextTick()

  • 你在修改数据的时候就相当于一个同步任务(你不要说为什么修改数据是一个同步任务,而不是异步任务,这是相对的,你修改数据到视图(dom)更新是两件事,你又想两件事一起执行这是不可能的(js是单线程)所以你要去更新视图的时候就要开启一个异步任务了)
  • Vue 开启一个异步队列,并缓冲在此事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。
  • 同步任务执行完毕,开始执行异步 watcher 队列的任务,更新 DOM 。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel 方法,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
  • 此时通过 Vue.nextTick 获取到改变后的 DOM 。通过 setTimeout(fn, 0) 也可以同样获取到
  • 简单总结事件循环:

同步代码执行 -> 查找异步队列,推入执行栈,执行Vue.nextTick[事件循环1] ->查找异步队列,推入执行栈,执行Vue.nextTick[事件循环2]…

应用场景

  • 获取修改后的值
<template>
  <div class="hello">
    <div>
      <button id="firstBtn" @click="testClick()" ref="aa">{{testMsg}}</button>
    </div>
  </div>
</template>
 
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      testMsg:"原始值",
    }
  },
  methods:{
    testClick:function(){
      let that=this;
      that.testMsg="修改后的值";
      console.log(that.$refs.aa.innerText);   //that.$refs.aa获取指定DOM,输出:原始值
    }
  }
}
</script>

使用this.$nextTick

methods:{
    testClick:function(){
      let that=this;
      that.testMsg="修改后的值";
      that.$nextTick(function(){
        console.log(that.$refs.aa.innerText);  //输出:修改后的值
      });
    }
  }
  • 当项目中你想在改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;通俗的理解是:更改数据后当你想立即使用js操作新的视图的时候需要使用它
<template>
  <div class="hello">
    <h3 id="h">{{testMsg}}</h3>
  </div>
</template>
 
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      testMsg:"原始值",
    }
  },
  methods:{
    changeTxt:function(){
      let that=this;
      that.testMsg="修改后的文本值";  //vue数据改变,改变dom结构
      let domTxt=document.getElementById('h').innerText;  //后续js对dom的操作
      console.log(domTxt);  //输出可以看到vue数据修改后DOM并没有立即更新,后续的dom都不是最新的
      if(domTxt==="原始值"){
        console.log("文本data被修改后dom内容没立即更新");
      }else {
        console.log("文本data被修改后dom内容被马上更新了");
      }
    },
 
  }
}
</script>

使用Vue.nextTick后

changeTxt:function(){
      let that=this;
      that.testMsg="修改后的文本值";  //修改dom结构
       
      that.$nextTick(function(){  //使用vue.$nextTick()方法可以dom数据更新后延迟执行
        let domTxt=document.getElementById('h').innerText; 
        console.log(domTxt);  //输出可以看到vue数据修改后并没有DOM没有立即更新,
        if(domTxt==="原始值"){
          console.log("文本data被修改后dom内容没立即更新");
        }else {
          console.log("文本data被修改后dom内容被马上更新了");
        }
      });
    },
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值