为什么需要虚拟列表
日常开发中,经常需要处理一个大数据量的列表,可能是需要展示、勾选等;
如果我们用html原生的标签实现,性能到还好。但是现在大多都是用第三方组件库开发(例如element-ui),以便提升开发效率;
如果我们同时展示、勾选千条数据的时候,页面将会卡主,甚至崩掉;
虚拟列表的方案正是为了解决这类前端大数据量展示、操作卡顿的问题;
虚拟列表原理
虚拟列表只对部分区域进行渲染,对区域外的DOM进行销毁操作。
如果用户上下滚动,那DOM元素就会一直创建、销毁(做好笔记,这是考试重点)。
实现多选框组件(万条数据不卡顿)
网上插件很多,不重复造轮子了,本次案例使用的插件 vue-virtual-scroll-list,详细参数配置请查看官网
要实现大数据量的展示和勾选
1.核心点在vue的 mixins 中注册事件 dispatch (这是官网的案例代码);
2.在组件中使用 $on 订阅虚拟滚动插件 data-component 的勾选事件;
3.在虚拟列表的子组件中,在mounted钩子改变勾选状态,因为随着列表滚动,子组件在不断被创建、销毁;’
tips:相关知识,请查看相应链接。本案例未实现默认值、全选等功能,你可以根据实际业务,对组件二次改造。
调用效果及代码
全局混入mixins(核心代码)
/*
* @Date: 2022-01-07 16:21:56
* @Author: surewinT 840325271@qq.com
* @LastEditTime: 2022-05-13 22:25:00
* @LastEditors: surewinT 840325271@qq.com
* @Description: mixin 混入
*/
import Vue from \'vue\'
Vue.mixin({
data() {
return {}
},
methods: {
// 组件事件传递
dispatch(componentName, eventName, ...rest) {
let parent = this.$parent || this.$root
let name = parent.$options.name
while (parent && (!name || name !== componentName)) {
parent = parent.$parent
if (parent) {
name = parent.$options.name
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(rest))
}
}
}
})
组件源码(p-virtual-check)
目录结构
├── p-virtual-check
├── index.vue # 组件入口
├── listItem.vue # 子组件-勾选框
index.vue
listItem.vue
{{ source.label }}
实现穿梭框组件(万条数据不卡顿)
穿梭框组件的核心代码跟上述的多选框组件一致,只不过多了搜索、勾选去重等功能,整体的功能更为复杂;
你可以根据实际业务,添加插槽、修改默认值等;
调用效果及代码
组件源码(p-virtual-transfer)
目录结构
├── p-virtual-transfer
├── index.vue # 组件入口
├── listItem.vue # 子组件-勾选框
├── virtualList.vue # 子组件-列表
index.vue
listItem.vue
{{ source[dataLabel] }}
virtualList.vue
{{ title }}
{{ checkNum }}