四时宝库

程序员的知识宝库

前端干货分享:Vue2.X中nextTick到底是干啥的?原理是什么?



Vue文档中对nextTick关于nextTick的介绍语焉不详,官网的解释如下:

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

那么nextTick的应用场景是什么?光说不练假把式,先上代码。


测试代码很简单,重点在于 methods里面的changeMsg方法。

  1. 我们修改了data里的message的数据。
  2. 我们希望messageOne能够获取到DOM元素 messageDiv里面的内容。

那么我们再看下运行结果看看是不是我们想要的



我们看到 使用了this.nextTick方法的结果是我们想要的结果,而直接获取数据的方式并没有拿到最新的数据。

我们为什么要使用nextTick呢?

官网中的解释如下:

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。


例如,当你设置 vm.someData = 'new value',该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。多数情况我们不需要关心这个过程,但是如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。

说了一大堆,总结一下(面试的时候可能用被问到)到简单概况起来就是:

  • Vue中DOM的更新是异步的。
  • 虽然Vue一直强调的是数据驱动视图,但是,有时候不可避免要操作DOM的。
  • 在数据变化之后等待 Vue 完成更新 DOM这是一个异步执行的过程,需要用nextTick来搞定。


nextTick使用情景

在Vue生命周期的created()钩子函数进行的DOM操作的时候需要要放在Vue.nextTick()的回调函数中。

为啥呢?如果不熟悉created()钩子的话可以再翻看一下Vue的生命周期,created函数执行的时候DOM元素还没有进行过渲染,这个时候操作DOM毛用也没有,所以需要将DOM操作放在Vue.nextTick()的回调方法中去搞定。

当然你可以选择在mounted()钩子里去操作DOM,这个时候所有的DOM都挂载到跟元素上并渲染完毕了。这个时候操作DOM元素是没有任何问题的。

数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

nextTick 函数的实现原理

简单说说面试的时候可以拿去吹牛逼。写太多怕大家也不喜欢看。

  1. 先定义了一个callbacks 存放所有的nextTick里的回调函数
  2. 然后判断一下当前的浏览器内核是否支持 Promise,如果支持,就用Promise来触发回调函数
  3. 如果不支持Promise再看看是否支持MutationObserver,是一个可以监听DOM结构变化的接口,观察文本节点发生变化时,触发执行所有回调函数。
  4. 如果以上都不支持就只能用setTimeout来完成异步执行了。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接