Vue2如何实现数组元素生成即渲染而非全部完成后再渲染
在Vue2中实现生成字符串时逐个渲染的方案
你需要生成10000个随机字符串并添加到数组,希望每个元素生成后立即渲染,而非等待全部完成。原代码的同步循环会阻塞JavaScript线程,导致浏览器无法在循环过程中进行DOM渲染,所有元素只能在循环结束后一次性显示。以下是两种可行的解决方案:
方法1:利用requestAnimationFrame拆分任务
requestAnimationFrame会在浏览器下一次重绘前执行回调,可将生成任务拆分为多个小批量任务,让浏览器有时间在任务间隙完成DOM渲染。
修改后的完整代码:
<div id="app"> <button @click="generateWords()">Generate words</button> <input v-model="search" type="text" /> <ul> <li v-for="(word, index) in words" :key="index"> {{ word }} </li> </ul> </div> <script> export default { name: 'App', data() { return { words: [], count: 10000, currentIndex: 0 }; }, methods: { generateWord() { const symbols = 'abcdefghijklmnopqrstuvwxyz1234567890'; let word = ''; while (word.length < 100) { word += symbols[Math.floor(Math.random() * symbols.length)]; } return word; }, generateWords() { this.currentIndex = 0; this.words = []; // 清空历史内容 const generateBatch = () => { // 每次生成10个,可根据需求调整批量大小 const batchSize = 10; const end = Math.min(this.currentIndex + batchSize, this.count); for (; this.currentIndex < end; this.currentIndex++) { const word = this.generateWord(); this.words.push(word); } if (this.currentIndex < this.count) { requestAnimationFrame(generateBatch); } }; requestAnimationFrame(generateBatch); } } }; </script>
说明:通过拆分批量任务,浏览器能在每批任务完成后触发渲染,平衡生成速度和实时性。调整batchSize可控制每批生成的数量,数值越大总生成速度越快,但实时渲染的间隔会变长。
方法2:使用async/await配合微任务延迟
通过async函数和微任务延迟,让JavaScript线程在每次生成后释放执行权,允许Vue处理响应式更新和浏览器渲染。
修改后的完整代码:
<div id="app"> <button @click="generateWords()">Generate words</button> <input v-model="search" type="text" /> <ul> <li v-for="(word, index) in words" :key="index"> {{ word }} </li> </ul> </div> <script> export default { name: 'App', data() { return { words: [], count: 10000 }; }, methods: { generateWord() { const symbols = 'abcdefghijklmnopqrstuvwxyz1234567890'; let word = ''; while (word.length < 100) { word += symbols[Math.floor(Math.random() * symbols.length)]; } return word; }, async generateWords() { this.words = []; // 清空历史内容 for (let i = 0; i < this.count; i++) { const word = this.generateWord(); this.words.push(word); // 释放线程,让Vue完成DOM更新 await Promise.resolve(); } } } }; </script>
说明:每次生成单个字符串后,通过await Promise.resolve()触发微任务,让事件循环优先处理Vue的响应式更新和浏览器渲染,之后再继续下一次生成。如果觉得逐个渲染过于频繁,也可以改为每N个字符串后执行一次await,减少渲染触发次数。
原代码错误修正
原代码中存在两处问题:
- 循环条件
count> i未引用实例的this.count,会导致未定义变量报错; v-for的:key="word.id"无效,因为生成的字符串没有id属性,改为使用索引index或字符串本身作为key即可。
内容的提问来源于stack exchange,提问作者Danil Fotin
相关产品推荐
相关产品推荐

