首页 > 其他分享 >说说nextTick的使用和原理?

说说nextTick的使用和原理?

时间:2022-11-28 16:04:00浏览次数:65  
标签:nextTick Vue 函数 DOM 更新 使用 原理 执行

分析

这道题及考察使用,有考察原理,nextTick在开发过程中应用的也较少,原理上和vue异步更新有密切关系,对于面试者考查很有区分度,如果能够很好回答此题,对面试效果有极大帮助。

答题思路

  1. nextTick是做什么的?
  2. 为什么需要它呢?
  3. 开发时何时使用它?抓抓头,想想你在平时开发中使用它的地方
  4. 下面介绍一下如何使用nextTick
  5. 原理解读,结合异步更新和nextTick生效方式,会显得你格外优秀

回答范例:
1.nextTick是等待下一次DOM更新刷新的工具方法。(其实一句话就可以把$nextTick这个东西讲明白:就是你放在 $ nextTick 当中的操作不会立即执行,而是等数据更新、DOM更新完成之后再执行,这样我们拿到的肯定就是最新的了。
再准确一点来讲就是 $nextTick方法将回调延迟到下次DOM更新循环之后执行。(看不懂这句人话的,可以看上面)

2.Vue有个异步更新策略,意思是如果数据变化,Vue不会立刻更新DOM,而是开启一个队列,把组件更新函数保存在队列中,在同一事件循环中发生的所有数据变更会异步的批量更新。这一策略导致我们对数据的修改不会立刻体现在DOM上,此时如果想要获取更新后的DOM状态,就需要使用nextTick。

开发时,有两个场景我们会用到nextTick

3.created中想要获取DOM时;
响应式数据变化后获取DOM更新后的状态,比如希望获取列表更新后的高度。
4.nextTick类型

function nextTick(callback?: () => void): Promise<void>

所以我们只需要在传入的回调函数中访问最新DOM状态即可,或者我们可以await nextTick()方法返回的Promise之后做这件事。

5.

在Vue内部,nextTick之所以能够让我们看到DOM更新后的结果,是因为我们传入的callback会被添加到队列刷新函数(flushSchedulerQueue)的后面,这样等队列内部的更新函数都执行完毕,所有DOM操作也就结束了,callback自然能够获取到最新的DOM值。

<script>
import { nextTick } from 'vue'

export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    async increment() {
      this.count++

      // DOM 还未更新
      console.log(document.getElementById('counter').textContent) // 0

      await nextTick()
      // DOM 此时已经更新
      console.log(document.getElementById('counter').textContent) // 1
    }
  }
}
</script>

<template>
  <button id="counter" @click="increment">{{ count }}</button>
</template>

 

给了一个count,想要在界面中绑定展示。一开始是0,如果用户点了increment,希望这个count能够++,我们希望界面中能够变成1,可是在紧接着的console.log中你会发现它并没有更新,结果仍然为0,并不是1,那么怎么输出1呢?await nextTick(),后面再输出结果就是1了。为什么会这样呢?这就是nextTick()带给我们最关键的东西了。说白了,就是nextTick()会返回一个promise,未来在异步的方式再来调用我们这行代码。也就是说nextTick()下的console.log将来执行的时候我们的DOM已经更新了。还有一种方式就是nextTick()中间加一个回调函数,在回调函数中输出我们的console.log里面的那一行代码。这样也是可以的。

具体地源码分析可以看面试题:Vue中$nextTick原理:讲的很清晰
总结一下:就是 $nextTick将回调函数放到微任务或者宏任务当中以延迟它地执行顺序;

重要的是理解源码中它的三个参数的意思:

callback:我们要执行的操作,可以放在这个函数当中,我们没执行一次$nextTick就会把回调函数放到一个异步队列当中;
pending:标识,用以判断在某个事件循环中是否为第一次加入,第一次加入的时候才触发异步执行的队列挂载
timerFunc:用来触发执行回调函数,也就是Promise.then或MutationObserver或setImmediate 或setTimeout的过程
理解之后,在看整个$nextTick里面的执行过程,其实就是把一个个 $nextTick中的回调函数压入到callback队列当中,然后根据事件的性质等待执行,轮到它执行的时候,就执行一下,然后去掉callback队列中相应的事件。

面试版
说说nextTick吧
nextTick:在下次DOM更新循环结束之后执行延迟回调。

nextTick知道吗?
这句话扩展开来说,就是由于Vue中DOM更新是「异步执行」的,即修改数据时,视图不会立即更新,而是会监听数据变化,并缓存在同一事件循环中,等同一数据循环中的所有数据变化完成之后,再统一进行视图更新。经常我们会在还未更新的时候就使用了某个元素,这样是拿不到变更后的dom的,所以为了确保能够得到更新后的DOM,所以设置了nextTick()方法。在修改数据之后立即使用这个方法,获取更新后的DOM。简单概括,vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick可以获取数据更新后最新dom的变化。

在项目中什么时候用呢?
比如,当我们需要在生命周期的created()函数进行一些DOM操作的时候一定、要把相关代码放在Vue.nextTick()的回调函数中。原因:在created钩子函数中,DOM还未进行任何渲染,此时进行DOM操作是没用的,所以如果要在这里操作dom,一定要将相关js代码放进
Vue.nextTick回调函数中。又或者,在数据变化后要执行某个动作,而这个动作需要使用随数据变化而改变的DOM结构的时候,也需要把相关逻辑写入Vue.nextTick ()回调函数中。

$nextTick既然把它传入的方法变成微任务了,那它和其它微任务的执行顺序是怎样的呢?
这简单来说就是谁先挂载Promise对象的问题,在调用 $nextTick方法时就会将其闭包内部维护的执行队列挂载到Promise对象,在数据更新时Vue内部首先就会执行 $nextTick方法,之后便将执行队列挂载到了Promise对象上,其实在明白Js的Event Loop模型后,将数据更新也看做一个 $nextTick方法的调用,并且明白 $nextTick方法会一次性执行所有推入的回调,就可以明白执行顺序的问题了。

$nextTick和nextTick区别
$ nextTick和nextTick区别就是nextTick多了一个context参数,用来指定上下文。但两个的本质是一样的,$nextTick是实例方法,nextTick是类的静态方法而已;实例方法的一个好处就是,自动给你绑定为调用实例的this罢了。

 

标签:nextTick,Vue,函数,DOM,更新,使用,原理,执行
From: https://www.cnblogs.com/caijinghong/p/16932420.html

相关文章

  • 在非k8s 环境下 的应用 使用 Dapr Sidekick for .NET
    在k8s环境下,通过Operator可以管理Daprsidecar,在虚拟机环境下,我们也是非常需要这样的一个管理组件,类似下图:​​​​在这张图片中,在上图左面,我们看到了“dapr.exe”、我们......
  • vue的.sync修饰符用法及原理详解
    vue.sync的历史vue.sync修饰符最初存在于vue1.0版本里,但是在2.0中被移除了。但是在2.0发布之后的实际应用中,vue官方发现.sync还是有其适用之处,比如在开发可复......
  • 在Expression Blend中使用XAML建立3D应用程序
    本文的目的是在Blend环境中研究WindowsPresentationFoundation(WPF)的3D特性,首先我们导入一个已经建立好的3D模型到程序中,使用动画让其旋转。然后,我们......
  • Electron-vue 使用Element-UI el-table 不显示
    在Electron-Vue中引入Element-UI,发现el-table显示空白,查资料发现只需要在.electron-vue/webpack.renderer.config里面白名单模块加上 'element-ui'  //修改前......
  • 使用 nRoute 框架来实现基于 Silverlight 的桌面应用
    nRouteFramework是codeplex中的一个开源项目,你可以使用nRoute实现基于Silverlight/WPF的类似桌面应用的框架。nRoute实现类似于.net.........
  • Vue3+Vite项目中 使用WindiCSS.
    之前工作有了解过根据类名来写元素的样式,一听就发出疑问:这样写项目可读性恐怕不是很好吧。。。  之后来到杭州工作后,开始使用WindiCSS后发现真香!!! 由于近期所写的项......
  • shell 使用jq解析json字符串数组
    echojson.txt|jq'.' 输出整个json字符串echojson.txt|jq'.[0]' 取出数组中第一个objectechojson.txt|jq'.[0].name' 取出数组第一个object中键为name的值......
  • 使用微信的你千万不要透露这串数字!赶紧告诉家里人
    "IT有得聊”是机械工业出版社旗下IT专业资讯和服务平台,致力于帮助读者在广义的IT领域里,掌握更专业、实用的知识与技能,快速提升职场竞争力。 据不完全统计,中国网民规模达7.1......
  • 详述怎么使用Linux救援模式
    当你的Linux系统出现问题时你会怎么办,直接重新安装,还是用Linux救援模式。或许你对这个模式很陌生但是并不妨碍他会对你有很大的帮助,可以帮你挽回很多重要的数据,是你不必很伤......
  • Tomcat源码分析使用NIO接收HTTP请求(四)----解析请求头
    User-Agent:PostmanRuntime/7.28.4Accept:text/htmlPostman-Token:c125824d-ae13-4082-9ae0-87c1750476b8Host:localhost:8000Accept-Encoding:gzip,deflate,brCon......