Vue 展示巨量数据,vue-virtual-scroller 使用说明 vue3 vue2
一、遇到的问题
最近在做一个小工具,其中需要展示一个巨量数据列表,数据有 8万 多条。
最开始是直接让它渲染的,结果用了 60 秒之多,我以为是数据处理耗时过多,经过排查发现是 dom
的渲染用时过长,数据处理其实只用了 100ms 左右,如下图:
二、解决方案 vue-virtual-scroller
所以,目前主要需要解决的就是:如何能流畅展示这么多数据。搜了下,搜到 vue-virtual-scroller
这个插件。
它的主要功能:处理巨量列表的展示。
原理是:它只会把展示给用户的那部分 dom 渲染出来,比如滚到上面的 dom 就会回收掉。这个跟 iOS
的 ReuseableCell
很像,iOS 那个就是复用的。
它会生成一个很长的 dom,然后根据这个 dom 的滚动距离,计算应该渲染展示的内容列表。
三、vue2 使用 vue-virtual-scroller
1. 安装
安装 vue-virtual-scroller
npm i vue-virtual-scroller
安装完后 package.js 中会多出
"vue-virtual-scroller": "^1.0.10"
2. vue2 中引入 vue-virtual-scroller
main.js
中引入 vue-virtual-scroller
并 use
它
// vue virtual scroller
import "vue-virtual-scroller/dist/vue-virtual-scroller.css" // 引入它的 css
import VueVirtualScroller from "vue-virtual-scroller" // 引入它
Vue.use(VueVirtualScroller) // use 它
vue-virtual-scroller
中包含这几个组件,具体都能做什么可以看官方文档,这里只介绍 RecycleScroller
- RecycleScroller
- DynamicScroller
- DynamicScrollerItem
3. 使用
vue 的内容
<recycle-scroller
class="virtual-list"
:buffer="1000"
:prerender="200"
style="height: 400px"
:item-size="24"
key-field="id"
:items="tableData">
<template v-slot="{ item, index }">
<div class="list-item" :key="index">
<span>{{ item.id }}</span>
<span>{{ item.name }}</span>
</div>
</template>
</recycle-scroller>
data() {
return {
tableData: []
}
},
created() {
for (let i = 0; i < 100000; i++) {
this.tableData.push({id: i, name: Math.random()})
}
}
注意!!!!!: 这里需要特别注意,
recycle-scroller
组件必须设置高度,自己计算也好,提前指定也好,必须设置,不然会出错。
4. Props 和 Slot 说明
recycle-scroller
的接收参数说明:官方文档
prop | 解释 |
---|---|
item-size | 元素高度,默认:null,需要设置这个高度,不然好像也会出错 |
items | 数组,列表数据源,主角 |
buffer | 加到可视区域上下的像素高度,可以适当调大,避免滚动出现的空白 |
key-field | 默认标识每行用的标识字段,默认是 id,如果你的 items 数据里没有 id,就自己想办法了,可以自己将源数据生成并添加第一行的唯一 id |
官方说明如下:
如果你指定的 keyField
存在重复的情况,就会出现列表内容缺失的情况 如下:
v-slot
可以为以下几个值: 官方文档
prop | 解释 |
---|---|
item | 展示中的元素个体 |
index | 返回每个元素在 items 中的位置 inex |
active | 元素是否处于 active 状态 |
5. 列表元素的高度设置注意事项
最好呢, prop 中的 itemSize
跟列表模板的高度一致。
比如上面代码中的例子, .list-item
的 css 高度最好设置成 prop 中 item-size
一致的高度 24px,一般通过 line-height: 24px
就能实现,如果有 padding 那就另算。
看一下如果这两个高度不匹配会出现什么情况:
比如我把 item-size
设置成了 15
远小于内部列表单元的高度,就会出现下面的情况
但如果你设置成了同样的高度,就非常正常了。
6. 效果展示
初始化的时候创建了 10万条 数据,载入毫无延迟
42万 也不成问题:
四、vue3 使用 vue-virtual-scroller
vue3 中使用的组件跟 vue2 只有引入的时候不同,其它都一样。
安装
npm i vue-virtual-scroller@next
安装完后 package.js
中会多出
"vue-virtual-scroller": "^2.0.0-alpha.1"
main.js
// vue virtual scroller
import "vue-virtual-scroller/dist/vue-virtual-scroller.css" // 引入它的 css
import VueVirtualScroller from "vue-virtual-scroller" // 引入它
app.use(VueVirtualScroller) // use 它
五、结语
所有的操作都在官方 API 文档中有,我只是摘取了部分,哪里不太明白的话可以去看原文档。
例子源码:
https://github.com/KyleBing/wubi-dict-editor/blob/master/view/index/index.html
可以查看在线例子:
https://kylebing.cn/tools/wubi-dict-editor-web/
https://kylebing.cn/e/#/demos/vueVirtualScroller
这是我做的另一个 electron
工具里的内容