当DOM中渲染的列表数据过多时,页面会非常卡顿,非常占用浏览器内存。可以使用虚拟列表来解决这个问题,即使有成百上千条数据,页面DOM元素始终控制在指定数量。

一、参考文档
https://www.npmjs.com/package/vue-virtual-scroll-list
二、引入
import VirtualList from 'vue-virtual-scroll-list'
components: {
  'virtual-list': VirtualList
}
<virtual-list
  :data-key="'productCode'"
  :data-sources="productList"
  :data-component="productItem"
  :keeps="20"
  style="overflow-y: auto;"
  @scroll="(e) => watchScroll(e)"
  ref="scrollList"
  :extra-props="{
    addCart
  }"
>三、参数
| 参数 | 描述 | 
|---|---|
| data-sources | 数据列表[数组] | 
| data-key | 列表 key 值 | 
| data-component | 列表子组件 | 
| keeps | 渲染最大 DOM 数量 | 
| extra-props | 额外参数,可传变量和方法 | 
| @scroll | 监听滚动事件 | 
四、注意
1、virtual-list 组件自身必须设置为滚动区域
style="overflow-y: auto;"2、子组件引入由原 components 注册改为在 data 注册
import productItem from '@components/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);


















