当前位置: 首页 > news >正文

【vue】vue面试高频问题之-$nextTick的作用和使用场景

nextTick的作用和使用场景
vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick就可以获取数据更新后最新DOM的变化

api文档

Vue.nextTick( [callback, context] )

  • 参数

    • {Function} [callback]
    • {Object} [context]
  • 用法

    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    // 修改数据
    vm.msg = 'Hello'
    // DOM 还没有更新
    Vue.nextTick(function () {// DOM 更新了
    })// 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
    Vue.nextTick().then(function () {// DOM 更新了})
    

    2.1.0 起新增:如果没有提供回调且在支持 Promise 的环境中,则返回一个 Promise。请注意 Vue 不自带 Promise 的 polyfill,所以如果你的目标浏览器不原生支持 Promise (IE:你们都看我干嘛),你得自己提供 polyfill。

  • 参考:异步更新队列

适用场景:
第一种:有时需要根据数据动态的为页面某些dom元素添加事件,这就要求在dom元素渲染完毕时去设置,但是created与mounted函数执行时一般dom并没有渲染完毕,所以就会出现获取不到,添加不了事件的问题,这回就要用到nextTick处理
第二种:在使用某个第三方插件时 ,希望在vue生成的某些dom动态发生变化时重新应用该插件,也会用到该方法,这时候就需要在 $nextTick 的回调函数中执行重新应用插件的方法,例如:应用滚动插件better-scroll时


第三种:数据改变后获取焦点

何为$nextTick

因为Vue的异步更新队列,$nextTick是用来知道什么时候DOM更新完成的。
详细解读:

我们先来看这样一个场景:有一个div,默认用 v-if 将它隐藏,点击一个按钮后,改变 v-if 的值,让它显示出来,同时拿到这个div的文本内容。如果v-if的值是 false,直接去获取div内容是获取不到的,因为此时div还没有被创建出来,那么应该在点击按钮后,改变v-if的值为 true,div才会被创建,此时再去获取,示例代码如下:

<div id="app"><div id="div" v-if="showDiv">这是一段文本</div><button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({el : "#app",data:{showDiv : false},methods:{getText:function(){this.showDiv = true;var text = document.getElementById('div').innnerHTML;console.log(text);}}
})
</script>


这段代码并不难理解,但是运行后在控制台会抛出一个错误:Cannot read property 'innnerHTML of null,意思就是获取不到div元素。这里就涉及Vue一个重要的概念:异步更新队列。

异步更新队列
Vue在观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所以数据改变。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。然后,在下一个事件循环tick中,Vue刷新队列并执行实际(已去重的)工作。所以如果你用一个for循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,这固然是一个很大的开销。
Vue会根据当前浏览器环境优先使用原生的Promise.then和MutationObserver,如果都不支持,就会采用setTimeout代替。
知道了Vue异步更新DOM的原理,上面示例的报错也就不难理解了。事实上,在执行this.showDiv = true时,div仍然还是没有被创建出来,直到下一个vue事件循环时,才开始创建。$nextTick就是用来知道什么时候DOM更新完成的,所以上面的示例代码需要修改为:

<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div><button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({el : "#app",data:{showDiv : false},methods:{getText:function(){this.showDiv = true;this.$nextTick(function(){var text = document.getElementById('div').innnerHTML;console.log(text);  });}}
})
</script>


这时再点击事件,控制台就打印出div的内容“这是一段文本“了。
理论上,我们应该不用去主动操作DOM,因为Vue的核心思想就是数据驱动DOM,但在很多业务里,我们避免不了会使用一些第三方库,比如 popper.js、swiper等,这些基于原生javascript的库都有创建和更新及销毁的完整生命周期,与Vue配合使用时,就要利用好$nextTick。

http://www.lryc.cn/news/99363.html

相关文章:

  • MySQL学习笔记之SQL语句执行过程查看
  • 如何以毫秒精度,查看系统时间以及文件的创建时间
  • 基于机器学习的情绪识别算法matlab仿真,对比SVM,LDA以及决策树
  • jMeter使用随记
  • [语义分割] DeepLab v3(Cascaded model、ASPP model、两种ASPP对比、Multi-grid、训练细节)
  • css - Media Query
  • 9.python设计模式【外观模式】
  • Webpack5 CopyPlugin的作用
  • kafka服务端允许生产者发送最大消息体大小
  • 台阶型Nim游戏博弈论
  • NestJS 的 中间件 学习
  • 搭建自己第一个golang程序
  • Mysql加锁过程
  • 财经界杂志财经界杂志社财经界编辑部2023年第19期目录
  • Linux常用命令——dpkg-split命令
  • 常见的二十种软件测试方法详解
  • Python(一)
  • git pull无效,显示 * branch master -> FETCH_HEADAlready up to date. pull无效解决方法
  • SK5代理与socks5代理
  • 【【51单片机红外遥控小风车】】
  • 如何连接远程服务器?快解析内内网穿透可以吗?
  • 【云边有个小卖部】上新《探秘Linux》第三章 Linux 软件包管理器 yum
  • 【深度学习】【Image Inpainting】Free-Form Image Inpainting with Gated Convolution
  • 游戏引擎UE如何革新影视行业?创意云全面支持UE云渲染
  • DB-GPT:强强联合Langchain-Vicuna的应用实战开源项目,彻底改变与数据库的交互方式
  • STM32CubeMX v6.9.0 BUG:FLASH_LATENCY设置错误导致初始化失败
  • K8s-资源管理(二)
  • 脉冲信号测试应如何选择示波器带宽?
  • OpenCV DNN模块推理YOLOv5 ONNX模型方法
  • ThirdAI 的私有和可个性化神经数据库:增强检索增强生成(第 3/3 部分)