---
date: 2022-08-12
title: Vue 延迟分批渲染 dom
category: experience
cover: https://tse1-mm.cn.bing.net/th/id/OIP-C.Ko-vkqS8ZJSwVrq2tIf1igHaDt?pid=ImgDet&rs=1
location: 甘肃
tags:

- Vue
- Dom

---

### 实际业务背景

从服务端获取到的数据可能有几千上万条，而这些每一条都要渲染成一个 `Dom` 一下子全部渲染则会导致加载时间太久 / 白屏时间过长

### 解决思路

既然一下子全部渲染出来会导致这个问题，那咱们就分批去渲染，每次渲染 `50` / `40` 条数据

### 在 `Vue` 上如何使用

```vue
<template>
  <ul>
    列表<br />
    <li v-for="(item,key) in list" :key="key">{{item}}</li>
  </ul>
</template>

<script lang="ts" setup>
import {ref} from "vue";

// 总 dom 数量，即后端返回数据数量
const domToatl = ref(0)
// 临时存放后端数据
const domData = ref([])
// 每次渲染的 dom 数量
const domOnce = 40
// 已经渲染的 dom 数量
const domCountOfRender = ref(0)
// 实际数据
const list = ref([])

const loop = () => {
  setTimeout(() => {
    // 每次只渲染 domOnce 条数据
    for (let i = 0; i < domOnce; i++) {
      // 当DOM渲染完就退出
      if (domCountOfRender.value >= domToatl.value && list.length >= domToatl.value) return;
      list.value.push(domData.value[domCountOfRender.value]);
      domCountOfRender.value += 1;
    }
    loop();
  }, 500);
}

const getData = () => {
  new Promise((resolve, reject) => {
    setTimeout(() => {
      let res = {total: 100000, data: []};
      for (let i = 0; i < res.total; i++) {
        res.data.push(i);
      }
      resolve(res);
    }, 100);
  }).then((res) => {
    domData.value = res.data;
    domToatl.value = res.total;
    loop();
  });
}
</script>
```