You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,减少渲染触发次数。

原代码错误修正

原代码中存在两处问题:

  1. 循环条件count> i未引用实例的this.count,会导致未定义变量报错;
  2. v-for的:key="word.id"无效,因为生成的字符串没有id属性,改为使用索引index或字符串本身作为key即可。

内容的提问来源于stack exchange,提问作者Danil Fotin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:35:39