当DOM中渲染的列表数据过多时,页面会非常卡顿,非常占用浏览器内存。可以使用虚拟列表来解决这个问题,即使有成百上千条数据,页面DOM元素始终控制在指定数量。
一、参考文档
https://www.npmjs.***/package/vue-virtual-scroll-list
二、引入
javascript">import VirtualList from 'vue-virtual-scroll-list'
***ponents: {
'virtual-list': VirtualList
}
<virtual-list
:data-key="'productCode'"
:data-sources="productList"
:data-***ponent="productItem"
:keeps="20"
style="overflow-y: auto;"
@scroll="(e) => watchScroll(e)"
ref="scrollList"
:extra-props="{
addCart
}"
>
三、参数
参数 | 描述 |
---|---|
data-sources |
数据列表[数组] |
data-key |
列表 key 值 |
data-***ponent |
列表子组件 |
keeps |
渲染最大 DOM 数量 |
extra-props |
额外参数,可传变量和方法 |
@scroll |
监听滚动事件 |
四、注意
1、virtual-list 组件自身必须设置为滚动区域
style="overflow-y: auto;"
2、子组件引入由原 ***ponents 注册改为在 data 注册
import productItem from '@***ponents/product/productItem';
data() {
return {
productList: [{productCode: 1, productName...}, {...}, ...], // 数据列表
productItem // 子组件
}
}
3、子组件商品数据统一改为 source
props: {
source: {
type: Object,
default() {
return {};
}
}
}
4、子组件不再使用$emit方式与父组件交互,将父组件方法声明在extra-props中,子组件通过props接收,需要$emit 的时候使用 props 中接收的方法
props: {
// 接收父组件方法
addCart: {
type: Function,
default: () => {}
}
}
methods: {
// 子组件点击加购按钮
clickAddCart(item) {
// 调用父组件加购方法
this.addCart(item)
}
}
5、回到顶部,虚拟列表不识别 scrollTop,使用虚拟列表特有的 scrollToIndex 或 scrollToOffset 方法回到顶部
this.$refs.scrollList.scrollToIndex(0);
注意:真机滑动列表过程中,页面滚动有惯性,点击回到顶部时,页面会白屏,可以在点击的时候先关闭滚动,回到顶部后再恢复
// 回到顶部先停止滚动,将overflow-y设置为hidden,解决滚动时回到顶部白屏问题
this.$refs.scrolList.$el.style['overflow-y'] = 'hidden';
this.$refs.scrolList.scrollToIndex(0);
// 回到顶部后再恢复滚动
this.$refs.scrolList.$el.style['overflow-y'] = 'auto';