vue dom更新,vue 异步更新
Vue中的数据更新是异步的,这意味着我们无法在修改数据后立即获得修改后的DOM元素。本文介绍了vue异步更新dom的实现,有兴趣的朋友可以参考一下。
目录
VUE异步更新DOM的原理1什么时候可以得到真正的DOM元素?2为什么Vue需要nextTick方法来获取最新的DOM?3为什么会这样。$nextTick能够获得更新的DOM吗?总结:vue异步更新数据对象的原理:vue中数据方法返回的对象;
Dep对象:每个数据属性将创建一个Dep来收集所有使用该数据的观察器对象;
Watcher对象:主要用于渲染DOM
Vue异步更新DOM的原理
Vue中的数据更新是异步的,这意味着我们无法在修改数据后立即获得修改后的DOM元素。
1 什么时候能获取到真正的DOM元素?
在Vue的nextTick回调中。
2 为什么Vue需要通过nextTick方法才能获取最新的DOM?
2.1 When调用Watcher更新视图时,不会直接更新,而是将Watcher添加到队列中,然后将具体的更新方法flushSchedulerQueue传递给nexTick进行调用。
//src核心观察者watcher . js scheduler.js//在更新一个数据时会依次执行下面的代码。
//1.触发数据集
//2.呼叫dep.notify
//3.Dep将遍历所有相关的观察器来执行更新方法。
类监视器{
//4.执行更新操作。
update() {
queueWatcher(这个);
}
}
常量队列=[];
函数queueWatcher(watcher: Watcher) {
//5.将当前观察器添加到异步队列中。
queue . push(watcher);
//6.执行异步队列并传入回调。
next tick(flushSchedulerQueue);
}
//更新视图的具体方法
函数flushSchedulerQueue() {
让观察者,id;
//排序,先渲染父节点,再渲染子节点。
//这样可以避免不必要的子节点渲染,比如父节点中带有false v-if的子节点,就不需要渲染了。
queue.sort((a,b)=a . id-b . id);
//遍历所有观察器进行批量更新。
for(索引=0;索引队列长度;索引){
watcher=queue[index];
//更新DOM
watcher . run();
}
}
2.2 nextTick -将传递的flushSchedulerQueue添加到回调数组中,然后执行timerFunc方法。
const回调=[];
让timerFunc
函数nextTick(cb?函数,ctx?对象){
let _ resolve
//1.将传入的flushSchedulerQueue方法添加到回调数组。
callbacks.push(()={
CB . call(CTX);
});
//2.执行异步任务
//这个方法会根据浏览器兼容性选择不同的异步策略。
timer func();
}
2.3 timerFunc方法——它是根据浏览器兼容性创建的异步方法。执行此方法后,将为特定的DOM更新调用flushSchedulerQueue方法。
让timerFunc
//确定是否与承诺兼容
如果(类型的承诺!==未定义){
timerFunc=()={
Promise.resolve()。然后(flush callbacks);
};
//确定它是否与MutationObserver兼容
//https://developer . Mozilla . org/zh-CN/docs/Web/API/mutation observer
} else if (typeof MutationObserver!==未定义){
设计数器=1;
const observer=new mutation observer(flush callbacks);
const textNode=document . create textNode(String(counter));
observer.observe(textNode,{
characterData:真的,
});
timerFunc=()={
计数器=(计数器1)% 2;
text node . data=String(counter);
};
//确定是否与setImmediate兼容。
//这个方法存在于一些IE浏览器中
} else if (typeof setImmediate!==未定义){
//这是一个宏任务,但比setTimeout要好
timerFunc=()={
set immediate(flush callbacks);
};
}否则{
//如果以上方法都不知道,则使用setTimeout 0
timerFunc=()={
setTimeout(flushCallbacks,0);
};
}
//异步执行结束后,执行所有回调方法,即执行flushSchedulerQueue。
函数flushCallbacks() {
for(设I=0;一份,长度;i ) {
回调[I]();
}
}
2.4提高逻辑判断能力
2.4.1判断has标识,避免添加相同的观察者;排队;
2.4.2判断等待标志,让所有守望者一个滴答更新;
2.4.3判断flushing logo,处理观察器渲染时可能产生的新观察器。
如果v-if条件被触发,则添加新的观察器渲染。
提示:nextTick只是由Promise、setTimeout等方法简单模拟的异步任务。
3 为什么this.$nextTick 能够获取更新后的DOM?
称之为。$nextTick实际上是调用图中的nextTick方法来执行异步队列中的回调函数。根据先入先出原则,修改数据触发的更新异步队列会先执行,执行后会生成一个新的DOM。然后当这个回调函数。$nextTick,就可以获得更新后的DOM元素。
//当我们使用这个的时候。$nextTick,我们实际上调用的是nextTick方法。
vue . prototype . $ next tick=Function(fn:Function){
返回nextTick(fn,this);
};
总结:vue异步更新的原理
修改Vue中的数据将触发与该数据相关的所有观察器进行更新。首先,所有的观察者将被添加到队列中。然后,调用nextTick方法来执行异步任务。在异步任务的回调中,对队列中的Watcher进行排序,然后执行相应的DOM更新。
关于vue异步更新dom的实现,本文到此结束。关于vue异步更新dom的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。