vue实现虚拟列表组件解决长列表性能问题

最近项目中需要用到列表的展示,且不分页。当数据加载太多时会造成性能问题。因此采用虚拟列表来优化

一、虚拟列表

真实列表:每条数据都展示到html上,数据越多,DOM元素也就越多,性能也就越差。

虚拟列表:只展示部分数据(可见区域展示数据),当屏幕滚动时替换展示的数据,DOM元素的数量是固定的,相比较真实列表更高效。

二、实现思路

vue实现虚拟列表组件解决长列表性能问题_第1张图片

难点与思考:

1. 如何计算需要渲染的数据

  • 数据可分为总数据,与需要渲染的数据,需要渲染的数据包括了可见区域与缓冲区域的数据
  • 通过单条数据占位的高度与可见区域的高度,算出可见区域的列表条数,再往上和往下扩展几条缓冲区域的数据(本次代码是以3倍可见区域的条数作为需要渲染的数据条数)

2. 何时替换数据

  • 监听滚动事件,渲染元素的第一条数据滚动出缓冲区域后(也就是可见区域第一个元素的index大于缓冲区域的条数时),就开始替换数据了,每次往上滑动一个元素,就替换一次数据。

3. 为何需要空白占位,如何计算空白占位的高度

  • 由于列表在滚动过程中会替换数据,如果没有空白占位的话,会导致第一个元素消失后,第二个元素立马替换了第一个元素的位置,会导致错位。如下图所示:

  • 因此滚动时,需要在元素消失后,补一个相同高度的空白占位
  • 上方的空白占位 = 消失的元素个数(也就是第一个渲染元素的index) * 单个元素的高度
  • 下方的空白占位 = 剩下需要渲染的元素个数(也就是最后一个元素的index与总数据条数的差值)* 单个元素的高度

其他注意事项:

  • 在使用v-for遍历渲染数据时,key的值使用index,不用itemid,可以避免该dom元素被重新渲染,只替换数据。
  • 下拉加载更多时,不要将整个数据替换了,而是追加到数据的后面,避免之前展示的数据被替换了。
  • 空白占位可以使用padding来占位,也可以使用DOM元素占位,使用DOM元素占位监听滚动事件时,应使用touchmovemousemove监听,避免dom元素高度变化后,又触发了scroll滚动事件。
  • 监听滚动事件应该采用节流的方式,避免程序频繁执行。
  • 监听滚动时加上passive修饰符,可以提前告知浏览器需要执行preventDefault,使滚动更流畅,具体功能可以参考vue官网。
  • 外层包裹的元素需要有固定高度,并且overflowauto,才能监听scroll滚动事件。

三、实现

最终实现效果

实现代码





模拟数据的后端代码

  • 这是本次用于模拟后端数据的代码,采用mockexpress
const Mock = require('mockjs')
const express = require('express')
const app = express()

let sum = 1 // mock的ID

// 根据入参生成num条模拟数据
function generatorList(num) {
  return Mock.mock({
    [`list|${num}`]: [
      {
        'id|+1': sum,
        title: "@ctitle(15,25)",
        from: "@ctitle(3,10)",
      }
    ]
  })
}
// 允许跨域
app.all('*', function (req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", '*');
  res.setHeader("Access-Control-Allow-Headers", '*');
  res.setHeader("Access-Control-Allow-Method", '*');
  next()
})
app.get('/data', function (req, res) {
  const { num } = req.query
  const data = generatorList(num)
  sum += parseInt(num)
  return res.send(data)
})
const server = app.listen(4000, function () {
  console.log('4000端口正在监听~~')
})

四、封装为组件

也可以封装为插件,此处为了方便就封装为组件

props:

  • allList : 所有数据
  • oneHeight : 单条元素的高度
  • lower : 距离底部多远时触发触底事件,默认50

event:

  • @scrollLower : 触底时触发

虚拟列表组件代码





使用代码





到此这篇关于在vue中实现虚拟列表组件,解决长列表性能问题的文章就介绍到这了,更多相关vue虚拟列表组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

你可能感兴趣的:(vue实现虚拟列表组件解决长列表性能问题)