如果nexttick用微任务实现,如何保证在执行nexttick里的回调时,已经重新渲染完了DOM?

来源:4-9 nextTick

weixin_慕姐4425141

2019-06-27

vue可以用promise来实现nextTick,而且vue的数据更新在源码中也是用的nextTick,但是连续执行两个微任务中间应该不会重新渲染DOM,这种情况下如果在数据更新之后直接调用了nextTick来获取重新渲染后的DOM,vue是如何让DOM执行完数据更新的微任务后就马上让浏览器重新渲染DOM的呢?

写回答

2回答

ustbhuangyi

2019-06-27

首先,浏览器的重新渲染的时机是在 microtask 执行完毕后,这点可以参考 https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
其次,问题是为什么在 nextTick 后才可以获取到渲染后的 DOM,是因为 nextTick 后才会触发 Vue 的重新渲染(这里并非浏览器渲染),它会执行 vm._update,vm._render,vm.__patch__ 一系列操作,其中 vm.__patch__ 函数内部最终会操作 DOM,这点很关键,当操作 DOM 后,接下来同步执行的 JS 代码就可以获取到渲染后的 DOM 结果,如果 JS 代码是获取宽高之类的,比如获取 offsetHeight,会强制浏览器做一次重绘,这样也能获取到渲染后的 DOM 结果。

2
0

Watson丶

2019-10-23

dom更新是在每个微任务后执行的,你在入口执行下面的代码就行了:


const dom = document.getElementById('app');


console.log('sync');


Promise.resolve().then(() => {

  dom.innerText = 'aaa';

});


Promise.resolve().then(() => {

  console.log(dom.innerText); // aaa

});



0
0

Vue.js 源码深入解析 深入理解Vue实现原理

全方位讲解 Vue.js 源码,进阶高级工程师

4986 学习 · 1038 问题

查看课程