详解从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实例了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持黑区网络。
