当前位置:首页 > 技术文章 > 正文内容

vue 基础- nextTick 的使用场景(vue nexttick用法)

前言

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

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

先来看个例子

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

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

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

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

异步更新队列

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

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

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

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

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

nextTick

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

如下是一段 nextTick 相关源码片段,你可以在 vue\src\core\util\next-tick.js 找到:

它会有什么作用呢?

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

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

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

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

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

总结

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

关于我

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

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

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

相关文章

Vue3 中,父子组件如何传递参数?(vue父子组件传递数据方法)

在 Vue3 中,组件化开发是非常重要的特征,那么组件之间传值就是开发中常见的需求了。组件之间的传值三种方式:父传子、子传父、非父子组件传值。一、父传子( defineProps )父组件主要通过使用...

Vue3开发极简入门(16):祖孙组件间通信之provide&inject

前文说了Vue的组件间关系,有父子、爷孙、其他关系。例如之前的Father、Son是父子关系,App与Son就是爷孙关系。而props的Son,与emits的Son,就是其他关系。前文的props是父...

Vue3开发极简入门(15.1):emits补完-结合v-model

之前代码是通过按钮触发emit,如果希望输入框里的内容在输入之后也能同步到父组件,就可以结合v-model的update事件来操作,具体如下。Son2.vue:<template>...

Vue基础(vue基础组件文件名符合规范的是)

Vue 是什么,它的核心特点有哪些?Vue 是一款渐进式 JavaScript 框架,它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助开发者用...

学习ES6- 入门Vue(大量源代码及笔记,带你起飞)

ES6学习网站: https://es6.ruanyifeng.com/箭头函数普通函数//普通函数 this 指向调用时所在的对象(可变) let fn = function fn(a, b) {...

vue3源码分析——实现组件通信provide,inject

引言<<往期回顾>>vue3源码分析——rollup打包monorepovue3源码分析——实现组件的挂载流程vue3源码分析——实现props,emit,事件处理等vue3源...