Vue 虚拟滚动-展示大数据
背景介绍:
虚拟滚动的背景源于对处理大型数据集和提高用户界面性能的需求。随着计算机和移动设备性能的提升,人们开始处理越来越多的数据,并期望在用户界面上展示大量的内容。
然而,传统的渲染方式在处理大量数据时存在一些挑战。如果将整个数据集一次性加载到用户界面中,会导致内存占用过高,影响应用程序的性能和响应速度。此外,渲染所有数据也会增加页面的加载时间,使用户需要等待较长的时间才能看到完整的内容。
为了解决这些问题,虚拟滚动技术被引入。它通过只渲染当前可见的部分数据,而不是整个数据集,来提高性能和内存效率。当用户滚动内容时,虚拟滚动会动态加载和卸载数据,以确保只有当前可见的部分被渲染到屏幕上。
虚拟滚动的背景可以追溯到Web开发中的无限滚动(Infinite Scrolling)技术,该技术允许在网页上加载无限数量的内容,而不会影响整体性能。随后,虚拟滚动被广泛应用于各种用户界面框架和库中,如React、Angular、Vue等,以提供更好的用户体验和响应性能。
总的来说,虚拟滚动的背景是为了解决处理大型数据集时的性能问题,提高用户界面的渲染效率,并提供更流畅的滚动体验。它通过动态加载和卸载可见数据的方式,使得应用程序能够高效地处理大量数据而不牺牲性能和用户体验。
虚拟滚动插件
虚拟滚动的插件有很多,比如 vue-virtual-scroller、vue-virtual-scroll-list、react-tiny-virtual-list、react-virtualized 等
一、遇到的问题
最近在做的一个小工具中需要解决一个展示巨量数据列表的问题,数据有 8万 多条。
刚开始我是直接让它渲染的,结果用了 60 秒之多,我以为是数据处理耗时多,经过排查,发现是 dom 渲染用时长,数据处理其实只用了100ms 左右;
![](https://img.haomeiwen.com/i6286160/166bd647da88e97c.png)
二、解决方案 vue-virtual-scroller
所以,目前主要需要解决的就是:如何能流畅展示这么多数据,搜了下,搜到 vue-virtual-scroller 这个插件。
它主要能实现的功能:处理巨量列表的展示。原理是它只把展示给用户的那部分渲染出来,比如滚到上面的 dom 就回收掉。这个跟 iOS 的 ReuseableCell 很像,iOS 那个就是复用的。
它会生成一个很长的 dom,然后根据这个 dom 的滚动距离,计算应该渲染展示的内容列表。
安装
vue-virtual-scroller
npm i vue-virtual-scroller
main.js 引入
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'; // 引入它的 css
import VueVirtualScroller from 'vue-virtual-scroller'; // 引入它
Vue.use(VueVirtualScroller); // use
<template>
<div class="adminTest">
<basic-container>
<div style="margin-bottom:30px">总共数据:{{ tableData.length }}</div>
<recycle-scroller
class="virtual-list"
:buffer="10"
:prerender="11"
style="height: 400px;background:pink;"
:item-size="50"
key-field="id"
:items="tableData">
<template #default="{ item, index }">
<div :key="index" class="list-item">
<span style="display: inline-block; margin-right: 20px;">序号:{{ index+1 }}</span>
<span style="display: inline-block; margin-right: 20px;">报告名称:{{ item.reportName }} </span>
<span style="display: inline-block; margin-right: 20px;">类型:{{ item.reportType }}</span>
</div>
</template>
</recycle-scroller>
</basic-container>
</div>
</template>
<script>
import { fetchList } from '@/api/report-center/safe-report';
export default {
name: 'AdminTest',
components: {
},
data() {
return {
page: {
total: 0, // 总页数
currentPage: 1, // 当前页数
pageSize: 10000000, // 每页显示多少条,
isAsc: false // 是否倒序
},
tableData: []
};
},
computed: {
},
watch: {
},
mounted() {
this.getList(this.page);
},
methods: {
getList(page, params) {
fetchList(
Object.assign(
{
current: page.currentPage,
size: page.pageSize
},
params
)
).then(response => {
this.tableData = response.data.data.records;
this.page.total = response.data.data.total;
});
}
}
};
</script>
<style lang="scss">
</style>
页面展示4576条数据,dom 只有19条数据
![](https://img.haomeiwen.com/i6286160/809e86606ebed19a.png)