手机版

了解Vue中的nextTick

时间:2021-08-24 来源:互联网 编辑:宝哥软件园 浏览:

Vue中的nextTick涉及到Vue中DOM的异步更新,非常有意思。我对它有特殊的理解。其中,nextTick的源代码涉及到很多知识,很多人都不太懂。先根据我自己暂时的一些感受来介绍下nextTick。

一.例子

我们举个例子来了解一下Vue中的DOM更新和nextTick的功能。

模板

Div class=' app ' Div ref=' msgDiv ' { msg } }/Div Div v-if=' msg 1 ' Message get out $ next tick : { { msg 1 } }/Div Div v v-if=' msg 2 ' Message get out $ next tick : { { msg 3 } }/Div button @ click=' change msg '更改message/button/divvue实例

新Vue({ el: '。app ',data: { msg: 'Hello Vue ',msg1: ' ',msg2: ' ',msg3: '' },methods : { changemmsg(){ this . msg=' Hello world 'this.msg1=this。$refs.msgDiv.innerHTML这个。$nextTick(()={this。msg2=这个。参考文献。msgdiv.innerhtml})这一点。msg3=这个。参考文献。msgdiv.innerhtml}})后再单击

点击后,

从图中可以知道,msg1和msg3显示的内容仍然是转换前的内容,而msg2显示的内容是转换后的内容。根本原因是Vue中的DOM更新是异步的(后面会详细解释)。

二、应用场景

下面我们来了解一下nextTick的主要应用场景和原因。

在Vue生命周期的created()钩子函数中执行的DOM操作必须放在Vue.nextTick()的回调函数中。执行created () hook函数时,DOM根本不渲染,此时执行DOM操作无异于徒劳,所以这里需要把DOM操作的js代码放入Vue.nextTick()的回调函数中。与之对应的是挂载的()钩子函数,因为钩子函数执行的时候所有的DOM挂载和渲染都已经完成了,此时钩子函数中的任何一个DOM操作都没有问题。

当数据发生变化后要执行的一个操作,并且这个操作需要使用随数据变化而变化的DOM结构时,这个操作应该放入Vue.nextTick()的回调函数中。

具体原因在Vue官方文件中有详细说明:

Vue异步执行DOM更新。只要观察到数据变化,Vue就会打开一个队列,并在同一事件周期内缓冲所有数据变化。如果同一观察器被触发多次,它将只被推入队列一次。这种在缓冲过程中删除重复数据的方法对于避免不必要的计算和DOM操作非常重要。然后,在下一个事件循环“滴答”中,Vue刷新队列并执行实际的(已消除重复数据的)工作。Vue试图在内部为异步队列使用本机Promise.then和MessageChannel。如果执行环境不支持,将使用setTimeout(fn,0)。

例如,当您设置vm.someData=“新值”时,组件不会立即重新呈现。当队列被刷新时,当事件循环队列被清空时,组件将在下一次“滴答”时被更新。在大多数情况下,我们不需要关心这个过程,但是如果您想在DOM状态更新后做一些事情,这可能会很棘手。虽然Vue.js通常鼓励开发人员以“数据驱动”的方式思考,避免直接接触DOM,但有时我们会这样做。要在数据更改后等待Vue完成DOM更新,可以在数据更改后立即使用Vue.nextTick(回调)。这样,回调函数将在DOM更新完成后被调用。

三、分析nextTick的源代码

影响

Vue.nextTick用于延迟一段代码的执行。它接受两个参数(回调函数和执行回调函数的上下文)。如果没有提供回调函数,将返回一个promise对象。

源代码

/** *将任务推迟到异步执行*/export const next tick=(function(){ const回调=[]let pending=false let timer func func next tichandler(){ pending=false const copy=回调。切片(0)回调。长度=0为(设I=0;长度;I){ copy[I]()} }//nextTick行为利用了微任务队列,可以通过本机答应我。然后或突变服务器/访问该队列//突变服务器有更广泛的支持,然而在iOS=9.3.3中的//UIWebView中,当在触摸事件处理程序中触发时,它被严重窃听。它//触发几次后完全停止工作.因此,如果原生//承诺可用,我们将使用它: /*伊斯坦布尔忽略如果*/如果(承诺类型!=='未定义'是动词(承诺)){风险值p=承诺。resolve()var日志错误=err={ console。错误(错误)}计时器函数=()={ p .然后(下一个刻度处理程序).catch(logError) //在有问题的UIWebViews中答应我,然后不会完全中断,但是//它会陷入一种奇怪的状态,回调被推入//微任务队列,但是队列没有被刷新,直到浏览器//需要做一些其他的工作,例如处理一个计时器。因此,我们可以//"强制"通过添加一个空计时器来刷新微任务队列if(isIOS)setTimeout(noop)} } else if(!国际工业生态学会类型的突变服务器!==' undefined '(是原生的(MutationObserver)| |//PhantomJS和iOS 7。x突变服务器。tostring()=='[object mutationobserverconconstructor]'){//在原生承诺不可用的地方使用突变服务器,//例如Phantomjs、iOS 7、Android 4.4 var计数器=1 var observer=new MutationObserver(next tick处理程序)var textNode=document。createtextnode(字符串(计数器))观察者。观察者。观察者(文本节点,文本节点,{字符:功能ctx?对象){ let _resolve回调。推(()={ if(CB){尝试{ CB。call(ctx)} catch(e){ handleError(e,CTX,' next tick ')} } else if(_ resolve){ _ resolve(CTX)} })if(!pending){ pending=true timerFunc()} if(!可换股债券类型的承诺!=='未定义'){ 0返回新的承诺(解析,拒绝)={ _resolve=resolve }) })()首先,先了解下一步中定义的三个重要变量。

回调

用来存储所有需要执行的回调函数

悬而未决的

用来标志是否正在执行回调函数

timerFunc

用来触发执行回调函数

接下来,了解nextTickHandler()函数。

函数next tick handler(){ pending=false const copy=回调。切片(0)回调。长度=0为(设I=0;长度;I){ 0份数[i]() } }这个函数用来执行回调里存储的所有回调函数。

接下来是将触发方式赋值给timerFunc。

先判断是否原生支持答应我,如果支持,则利用承诺来触发执行回调函数;否则,如果支持突变服务器,则实例化一个观察者对象,观察文本节点发生变化时,触发执行所有回调函数。如果都不支持,则利用定时器设置延时为0。最后是queueNextTick函数。因为下一步是一个即时函数,所以queueNextTick函数是返回的函数,接受用户传入的参数,用来往回调里存入回调函数。

上图是整个执行流程,关键在于timeFunc(),该函数起到延迟执行的作用。

从上面的介绍,可以得知timeFunc()一共有三种实现方式。

承诺变更服务器设置超时其中承诺和定时器很好理解,是一个异步任务,会在同步任务以及更新数字正射影像图的异步任务之后回调具体函数。

下面着重介绍一下突变服务器。

MutationObserver是HTML5中的一个新API,它是一个监控DOM变化的接口。他可以在一个DOM对象中监听子节点删除、属性修改、文本内容修改等等。

打电话的过程很简单,但有点不寻常:你需要先给他打个回电:

var mo=新突变服务器(回调)

通过将回调传递给突变观察者的构造函数,可以获得一个突变观察者实例,当突变观察者实例听到变化时,这个回调将被触发。

此时,您只将回调绑定到MutationObserver实例,他听的是哪个DOM、节点删除或属性修改,还没有设置。并且调用他的观察者方法可以完成这个步骤:

var DOM TArGet=DOM节点mo.observe (domtarget,{ character data : true//)表示对被监控文本内容的修改。})

nextTick中的MutationObserver的功能如上图所示。监控DOM更新后,调用回调函数。

实际上,使用MutationObserver的原因是nextTick想要一个异步API来执行我想在当前同步代码执行后执行的异步回调,包括Promise和setTimeout。深入还涉及到microtask等。暂时不懂就不深入介绍了。

摘要

以上是边肖介绍的Vue中的nextTick。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!如果你觉得这篇文章对你有帮助,请转载,请注明出处,谢谢!

版权声明:了解Vue中的nextTick是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。