这边记录分享一个最近在工作中遇到的问题
在没有获取后端接口的前提下,在mounted中写了大量的操作,将一个变量设置为true,在执行了大量的循环之后,再将这个值置为false,但是打印出来这个值都是正常的,但是页面渲染中这个值并没有改变。
在想几种办法之后,我发现将循环和置为false的操作放在setTimeOut中之后才能渲染正确,变量的值改变时间打印出来很短,所以问题出在页面的渲染上,我查找了很多之后发现了问题所在。
vue页面渲染机制
vue页面的渲染时间在一个宏任务结束之后或者在另一个微任务开始之前。
宏任务和微任务
宏任务有哪些
setTimeout,setInterval,Ajax,DOM事件等
微任务有哪些
Promise(的.then等回调函数),async/await等
例如:
console.log('start'); // 1
function foo(){
console.log('foo');
}
foo() // 2
setTimeout(function() { //异步代码中的宏任务,先挂起
console.log('setTimeout'); // 7
},1000)
new Promise(resolve =>{
console.log('promise'); // 3
resolve()
})
.then(function() { //异步代码中的微任务,先挂起
console.log('promise1');// 5
})
.then(function() { //异步代码中的微任务,先挂起
console.log('promise2');// 6
})
console.log('end'); // 4
执行的结果为
start
foo
promise
end
promise1
promise2
setTimeout
宏任务会先执行,然后是微任务,setTimeout是异步宏任务,会被当做新的宏任务去执行,而新的宏任务开始前会先把之前的微任务执行完,所以才有这样的结果。
所以当我在mounted中没有执行上述的宏任务或者微任务时,所以循环内的操作都将被看做是一整个宏任务,而且在循环之后并没其他宏任务,所以页面渲染在循环执行之前,渲染出现问题。所以这里我使用setTimeOut包裹起来循环,此部分是新的宏任务,所以页面会再次进行渲染,显示就正常了