nexttick使用场景_vue 基础- nextTick 的使用场景

e3dd83ba3d3cb630a7b33c5110b6c6dc.png

前言

《vue 基础》系列是再次回炉 vue 记的笔记,除了官网那部分知识点外,还会加入自己的一些理解。(里面会有部分和官网相同的文案,有经验的同学择感兴趣的阅读)

在开发时,是不是遇到过这样的场景,响应数据明明已经更新,但无法通过 dom 获取到。最后使用 nextTick 方法“包裹”后就能拿到。如果你不太清楚其中的原因,这篇或许能解开你的疑惑。

先来看个例子

这个例子很简单,主要来测试 nextTick 的作用。

定义了一个异步数据获取的方法 asyncDataFetch ,你可以把它当成一个接口请求,在执行 updateMsg 后,调用该方法,并最后通过 $refs 的方式来获取页面上的文本。

281159681b9a72f7fd3cce4d908b1503.png

页面模板

3688f1a951b90b22f2fa58174ac4960d.png

js 逻辑

虽然我们已经把接口返回的数据赋值给 this.asyncData ,但实际却没有在 $refs 中获取到 (html-2)。

从调试 console 中看到,其在 nextTick 方法中(html-3)被成功获取。

1f0651f0f8769de05ab265b1f43e0731.png

console 输出

异步更新队列

为什么例子中,明明把数据赋值给响应对象,但 html-2 中却没有更新呢?

这其实要回到 vue 异步更新队列 的解释中,查看原因。

虽然我们通过 this.someData = ‘new value’ 执行了赋值,但该响应数据并不是同步响应到页面模板中(即更新到页面 Dom 里)。

vue 更新 Dom 是一个异步过程,所以即使我们看到页面的渲染虽然被“刷新”了,但其实并不是数据一刷新,页面就被刷新,这尤其需要我们注意。

在这个异步队列中,vue 会根据不同的“异步” api 的支持情况来选择以最佳的方式执行 tick 。这些 api 包括:Promise、MutationObserver、setImmdiate、setTimeout。如果你了解浏览器的事件循环机制,将会对理解这个异步队列容易许多。

nextTick

好,知道 vue 中数据的更新时异步这一个概念后,那么为什么在 nextTick 执行相关代码能达到预期效果就基本知道大概了。

如下是一段 nextTick 相关源码片段,你可以在 vuesrccoreutilext-tick.js 找到:

c127bf67538a56a16dda8a0e5302118f.png

源码

它会有什么作用呢?

一旦调用了 nextTick ,就会把我们定义的 callback 函数方法推到 callbacks 这样一个全局变量中,这个 callbacks 就是 异步更新队列

然后会执行 timerFunc 一个异步 tick 方式封装。

如果当前客户端不支持 Promise、MutationObserver 等 api 方法时,将采用 setTimeout 后备方式:

83f83e03aef066d73a7ec7dae22242d4.png

setTimout 方式

当 vue 开始执行更新相关操作时,通过 flushCallbacks 方法来“清空”这个队列,内部执行每个队列元素:

9fc92a8461cfa72b1bfe1be729120249.png

源码

由于操作 dom 的成本非常高, vue 在数据 watch 层做了优化来处理整个过程的计算操作。

总结

说了为何使用 nextTick 能解决开发中一些“奇怪”的问题,并抛出 vue 的异步事件队列这个概念来解释这个原因。

关于我

一位“前端工程师”,乐于实践,并分享前端开发经验。

如果有问题或者想法,欢迎各位评论留言,愿大家共同进步。

关注【前端雨爸】,查阅更多前端技术心得。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值