详解从Vue.js源码看异步更新DOM策略及nextTick(4)
flushSchedulerQueue是下一个tick时的回调函数,主要目的是执行Watcher的run函数,用来更新视图
为什么要异步更新视图
来看一下下面这一段代码
<template> <div> <div>{{test}}</div> </div> </template>
export default { data () { return { test: 0 }; }, created () { for(let i = 0; i < 1000; i++) { this.test++; } } }
现在有这样的一种情况,created的时候test的值会被++循环执行1000次。
每次++时,都会根据响应式触发setter->Dep->Watcher->update->patch。
如果这时候没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。
所以Vue.js实现了一个queue队列,在下一个tick的时候会统一执行queue中Watcher的run。同时,拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对应的DOM的0变成1000。
保证更新视图操作DOM的动作是在当前栈执行完以后下一个tick的时候调用,大大优化了性能。
访问真实DOM节点更新后的数据
所以我们需要在修改data中的数据后访问真实的DOM节点更新后的数据,只需要这样,我们把文章第一个例子进行修改。
<template> <div> <div ref="test">{{test}}</div> <button @click="handleClick">tet</button> </div> </template>
export default { data () { return { test: 'begin' }; }, methods () { handleClick () { this.test = 'end'; this.$nextTick(() => { console.log(this.$refs.test.innerText);//打印"end" }); console.log(this.$refs.test.innerText);//打印“begin” } } }
使用Vue.js的global API的$nextTick方法,即可在回调中获取已经更新好的DOM实例了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持黑区网络。