本文共 1084 字,大约阅读时间需要 3 分钟。
这一篇介绍有关异步更新队列的知识,通过异步更新队列的学习和研究能够更好的理解Vue的更新机制
先看一个例子:
测试文本(默认隐藏)
一个很简单的例子,由v-if控制div是否被渲染,默认不渲染,点击按钮对div显示/隐藏做更改
按照以往的认识:
当点击按钮切换div显隐时,由于控制显隐的变量show被置为true,div会被渲染document.getElementById('div').innerHTML能够获取到内部html
实际执行结果
当点击按钮时,控制显隐的变量show被置为true随后document.getElementById('div').innerHTML时会报错错误原因:获取不到div元素
当再次点击按钮时,弹出alert:
这里就涉及到了Vue异步更新队列的概念了:
Vue在观察到数据发生变化时,并不是直接去更新DOM,而是会开启一个队列,并缓冲在同一事件循环中发生的所有数据变化在缓冲时,会去除重复的数据,避免多余的计算和DOM操作,在下一个事件循环tick中,刷新队列并执行已去重的工作
报错原因:
所以,在执行this.show=true时,div还未被创建出来,直到下一个Vue事件循环时才开始创建
这种查重机制使降低了Vue的开销:
for循环动态改变数据100次,查重后,只会执行最后一次改变,如果没有查重机制,页面将重绘100此,而前99此是无用的,会加大开销
异步更新队列实现的选择:
由于浏览器的差异,Vue会根据当前浏览器环境选择原生Promise.then和MutationObserver如果两者都不支持,会采用SetTimeout进行替代
了解了Vue异步更新DOM的原理之后,使用Vue提供的异步队列对上边的例子进行修改刚刚分析了报错的原因:在show=ture是div未被创建,在下一个事件循环中才开始创建Vue提供了$nextTick告知DOM何时更新完成,我们可以在$nextTick中进行div获取
测试文本(默认隐藏)
通过简单的修改后,首次点击获取内容不再报错
通过对异步更新队列的介绍,加深了对子组件渲染的了解异步更新队列是一个非常有用的东西,在使用第三方库时,很多并不是数据驱动DOM的这时就要使用JS原声库中创建,更新,销毁的生命周期,通过$nextTick与Vue配合使用