<template> <div> <ul> <li v-for="item in list1">{{item}}</li> </ul> <ul> <li v-for="item in list2">{{item}}</li> </ul> <ol> <li v-for="item in list3">{{item}}</li> </ol> <ol> <li v-for="item in list4">{{item}}</li> </ol> <ol> <li v-for="item in list5">{{item}}</li> </ol> </div> </template> <script type="text/javascript"> export default { data() { return { list1: [], list2: [], list3: [], list4: [], list5: [] } }, created() { this.composeList12() this.composeList34() this.composeList5() this.$nextTick(function() { // DOM 更新了 console.log('finished test ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) }, methods: { composeList12() { let me = this let count = 10000 for (let i = 0; i < count; i++) { Vue.set(me.list1, i, 'I am a 测试信息~~啦啦啦' + i) } console.log('finished list1 ' + new Date().toString()) for (let i = 0; i < count; i++) { Vue.set(me.list2, i, 'I am a 测试信息~~啦啦啦' + i) } console.log('finished list2 ' + new Date().toString()) this.$nextTick(function() { // DOM 更新了 console.log('finished tick1&2 ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) }, composeList34() { let me = this let count = 10000 for (let i = 0; i < count; i++) { Vue.set(me.list3, i, 'I am a 测试信息~~啦啦啦' + i) } console.log('finished list3 ' + new Date().toString()) this.$nextTick(function() { // DOM 更新了 console.log('finished tick3 ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) setTimeout(me.setTimeout1, 0) }, setTimeout1() { let me = this let count = 10000 for (let i = 0; i < count; i++) { Vue.set(me.list4, i, 'I am a 测试信息~~啦啦啦' + i) } console.log('finished list4 ' + new Date().toString()) me.$nextTick(function() { // DOM 更新了 console.log('finished tick4 ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) }, composeList5() { let me = this let count = 10000 this.$nextTick(function() { // DOM 更新了 console.log('finished tick5-1 ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) setTimeout(me.setTimeout2, 0) }, setTimeout2() { let me = this let count = 10000 for (let i = 0; i < count; i++) { Vue.set(me.list5, i, 'I am a 测试信息~~啦啦啦' + i) } console.log('finished list5 ' + new Date().toString()) me.$nextTick(function() { // DOM 更新了 console.log('finished tick5 ' + new Date().toString()) console.log(document.querySelectorAll('li').length) }) } } }</script>
以上代码的输出结果为:
finish list1 finish list2 finish list3 finish tick1&2 30000 finish tick3 30000 finish tick5-1 40000 finish test 50000
由上述可以得到以下结论:
1. 在同一事件循环中,只有当数据全部更新完毕后,才会执行nextTick(由先输出list1/2/3后,才输出tick数据得出)
2. 仅在同步环境中的数据完全更新完毕后,才会渲染DOM,显示页面(在setTimeout的回调执行之前,输出的li的长度都为30000)
3. 在同一事件循环中,nextTick会按照顺序执行
4. 只有同步环境执行完,且DOM渲染完毕后,才会执行异步任务的callback(由先输出list3后输出tick1&2得出)