Vxe UI vue vxe-table vxe-grid select 下拉框选项列表数据量超大过大时卡顿解决方法
查看 github
vxe-table 官网
vxe-table 本身支持虚拟滚动,数据量大也是支持的,但是如果在可编辑表格中使用下拉框,下拉框的数据量超大时,可能就会卡顿、老版本的下拉框不支持虚拟滚动,可以更新到 v4.7+ 版本,就可以使用下拉框虚拟滚动,配合表格虚拟滚动,渲染性能那是相当可以的。
可编辑表格使用下拉框
每个单元格中放着渲染1万条的下拉框丝滑流程
<template>
<div>
<vxe-grid v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script>
import Vue from 'vue'
export default {
data () {
const sexEditRender = {
name: 'VxeSelect',
options: [
{ label: '女', value: 'Women' },
{ label: '男', value: 'Man' }
]
}
const roleEditRender = {
name: 'VxeSelect',
props: {
filterable: true
},
options: []
}
const gridOptions = {
border: true,
editConfig: {
trigger: 'click',
mode: 'row'
},
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: 'Name', minWidth: 200, editRender: { name: 'VxeInput' } },
{ field: 'sex', title: '下拉单选', width: 200, editRender: sexEditRender },
{ field: 'role', title: '大数据量选项', width: 200, editRender: roleEditRender }
],
data: [
{ id: 10001, name: 'Test1', role: 'Develop', sex: '', sexList: [], type: '', typeList: [] },
{ id: 10002, name: 'Test2', role: 'Test', sex: 'Women', sexList: ['Man', 'Women'], type: '2-1', typeList: ['1-2', '2-1'] },
{ id: 10003, name: 'Test3', role: 'PM', sex: 'Man', sexList: [], type: '', typeList: [] }
]
}
return {
gridOptions,
sexEditRender,
roleEditRender
}
},
created () {
// 模拟后端接口
setTimeout(() => {
const list = []
for (let i = 0; i < 10000; i++) {
list.push({
value: `role${i}`,
label: `角色${i}`
})
}
this.roleEditRender.options = list
}, 100)
}
}
</script>
接下来测试下拉框渲染性能
加载1万条用时45毫秒
加载10万条用时398毫秒
加载30万条用时848毫秒
<template>
<div>
<p>
<vxe-button @click="loadData(1000)">加载1千条</vxe-button>
<vxe-button @click="loadData(10000)">加载1万条</vxe-button>
<vxe-button @click="loadData(100000)">加载10万条</vxe-button>
<vxe-button @click="loadData(300000)">加载30万条</vxe-button>
</p>
<vxe-select v-model="val1" v-bind="selectOptions"></vxe-select>
</div>
</template>
<script>
import Vue from 'vue'
import { VxeUI } from 'vxe-pc-ui'
export default {
data () {
const selectOptions = {
loading: false,
clearable: true,
filterable: true,
options: []
}
return {
val1: null,
selectOptions
}
},
methods: {
loadData (size) {
const list = []
this.selectOptions.loading = true
for (let i = 0; i < size; i++) {
list.push({
value: `${i}`,
label: `选项 ${i}`
})
}
setTimeout(() => {
const startTime = Date.now()
this.selectOptions.options = list
this.selectOptions.loading = false
this.$nextTick(() => {
VxeUI.modal.message({
content: `加载时间 ${Date.now() - startTime} 毫秒`,
status: 'success'
})
})
}, 300)
}
},
created () {
this.loadData(50)
}
}
</script>