宝哥软件园

vue源码下一步使用及原理解析

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

一下一个刻度的使用

某视频剪辑软件中数字正射影像图的更像并不是实时的,当数据改变后,vue会把渲染看守人添加到异步队列,异步执行,同步代码执行完成后再统一修改多姆,我们看下面的代码。

template div class=' box ' { msg } }/div/template export default { name : ' index },data () { return { msg: 'hello' },mounted(){ this。msg=' world ' let box=document。getelementsbyclassname(' box ')[0]控制台。日志(框。innerhtml)//hello } }可以看到,修改数据后并不会立即更新多姆多姆的更新是异步的,无法通过同步代码获取,需要使用下一步,在下一次事件循环中获取。

这个。msg=' world ' let box=document。getelementsbyclassname(' box ')[0]这.$ NextTick(()={ console。日志(框。InnerHTML)//world })如果我们需要获取数据更新后的数字正射影像图信息,比如动态获取宽高、位置信息等,需要使用下一步。

2数据变化数字正射影像图更新与下一步的原理分析

2.1 数据变化

某视频剪辑软件双向数据绑定依赖于ES5的Object.defineProperty,在数据初始化的时候,通过Object.defineProperty为每一个属性创建吸气剂与setter,把数据变成响应式数据。对属性值进行修改操作时,如this.msg=world,实际上会触发二传手。下面看源码,为方便越读,源码有删减。

双向数据绑定

数据改变触发设置函数

对象。define property(obj,key,{ enumerable: true,configurable: true,//数据修改后触发设置函数经过一系列操作完成数字正射影像图更新set:函数reactive setter(NewVal){ const value=getter?吸气器。调用(obj): val if(getter!setter)返回if (setter) { setter.call(obj,newVal)} else { val=newVal } childOb=!浅层观察(newVal) dep.notify() //执行资料执行防止通知方法}})执行资料执行防止通知方法

导出默认类Dep { constructor(){ this。id=uid这个。subs=[]} notify(){ const subs=this。潜艇。slice()(让i=0,l=subs.lengthI li ) { //实际上遍历执行了潜水艇数组中元素的更新方法潜艇.update() } }}当数据被引用时,如div{{msg}}/div,会执行得到方法,并向潜水艇数组中添加渲染观察者,当数据被改变时执行看守人的更新方法执行数据更新。

update () { /*伊斯坦布尔忽略else */if(这个。懒){这个。dirty=true } else if(this。同步){这个。run()} else { queueWatcher(this)//执行queueWatcher } }更新方法最终执行queueWatcher

函数queue Watcher(Watcher : Watcher){ const id=Watcher。id if(具有[id]==null){具有[id]=true if(!刷新){队列。push(watcher)} else {//如果已经在冲洗,根据其编号拼接该观察器//如果已经超过其id,它将立即运行。让i=queue.length - 1 while (i索引队列[i].id观察者。id){ I-}队列。拼接(I 1,0,观察器)}//队列刷新if(!等待){ //通过等待保证下一步只执行一次等待=真/最终queueWatcher方法会把flushSchedulerQueue传入到下一步中执行下一个勾号(FlushSchedulerqueue)} } }执行flushSchedulerQueue方法

函数flushescudioderqueue(){ currentflushttimestamp=GetNow())flushing=true让观察器,id.用于(索引=0;索引队列。长度;index){ watcher=queue[index]if(watcher。之前){ watcher。before()} id=watcher。编号有[id]=null //遍历执行渲染看守人的奔跑方法完成视图更新watcher.run() } //重置等待变量resetSchedulerState().}也就是说当数据变化最终会把flushSchedulerQueue传入到下一步中执行flushSchedulerQueue函数会遍历执行watcher.run()方法,watcher.run()方法最终会完成视图更新,接下来我们看关键的下一步方法到底是啥

2.2下一步

下一步方法会被传进来的回调推进回调数组,然后执行timerFunc方法

导出函数nextTick (cb?功能ctx?对象){ let _resolve //push进回调数组回调。push(()={ cb.call(ctx) }) if(!待定){待定=true //执行timerFunc方法timerFunc() }}timerFunc

let timerFunc//判断是否原生支持承诺类型!=='未定义'是动词(承诺){ const p=Promise。resolve()timer func=()={//如果原生支持承诺用承诺执行脸红回调然后(冲水回调)if(isIOS)setTimeout(noop)} isUsingMicroTask=true//判断是否原生支持MutationObserver} else if(!国际工业生态学会类型的突变服务器!==' undefined '(isNative(MutationObserver)| |//Phantomjs和IOs 7。x突变服务器。tostring()=='[object mutationobserverconconstructor]'){ let counter=1//如果原生支持突变观察器用突变观察器执行脸红回调常量观察器=新的突变观察器(刷新回调)const textNode=document。createtextnode(String(counter))观察者。observer(textNode,{ character data : true })timer func=()={ counter=(counter 1)% 2 TextNode。data=String(计数器)} isUsingMicroTask=true//判断是否原生支持setImmediate } else if(类型为setImmediate!=='未定义'是名词(setImmediate)){ timerFunc=()={//如果原生支持设置即时用设置即时执行脸红回调立即设置(刷新回调)}//都不支持的情况下使用setTimeout 0 } else { timerFunc=()={//使用定时器执行脸红回调设置超时(刷新回调,0)} }//齐平回调最终执行下一步方法传进来的回调函数函数FlushCallbacks(){ pending=false const copy=回调。切片(0)回调。长度=0为(设I=0;长度;I){ copy[I]()} } NextTick会优先使用微问,其次是宏任务。

也就是说下一步中的任务,实际上会异步执行,下一次点击(回调)类似于Promise.resolve().然后(回调),或者setTimeout(回调,0).

也就是说某视频剪辑软件的视图更新下一步(刷新调度队列)等同于setTimeout(flushSchedulerQueue,0),会异步执行flushSchedulerQueue函数,所以我们在this.msg=hello并不会立即更新多姆。

要想在数字正射影像图更新后读取数字正射影像图信息,我们需要在本次异步任务创建之后创建一个异步任务。

异步队列

为了验证这个想法我们不用下一步,直接用定时器实验一下。如下面代码,验证了我们的想法。

模板div class='框“{ msg } }/div/templatescriptexport默认{ name: ' index,data () { return { msg: 'hello' },mounted(){ this。msg=' world ' let box=document。getelementsbyclassname(' box ')[0]setTimeout(()={ console。日志(框。innerhtml)//world })} }如果我们在数据修改前下一步,那么我们添加的异步任务会在渲染的异步任务之前执行,拿不到更新后的多姆。

模板div class='框“{ msg } }/div/templatescriptexport默认{ name: '索引,data () { return { msg: 'hello' },mounted () { this .$ nextTick(()={ console。日志(框。innerhtml)//hello })这个。msg=' world ' let box=document。getelementsbyclassname(' box ')[0]} } 3总结

某视频剪辑软件为了保证性能,会把数字正射影像图修改添加到异步任务,所有同步代码执行完成后再统一修改多姆,一次事件循环中的多次数据修改只会触发一次watcher.run()。也就是通过下一个,下一个会优先使用微任务创建异步任务。

某视频剪辑软件项目中如果需要获取修改后的数字正射影像图信息,需要通过下一步在数字正射影像图更新任务之后创建一个异步任务。如官网所说,下一步会在下次数字正射影像图更新循环结束之后执行延迟回调。

参考文章

Vue nextTick机制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

更多资讯
游戏推荐
更多+