- 前端数据缓存数据:在首次请求到数据后,将数据缓存到前端(如使用 Redux, Vuex 或 localStorage), 后续再请求时,先检查缓存,如果数据在缓存中,则直接使用,无需重新请求后端。
- 懒加载和分页数据:可以考虑只加载当前可见的数据(如使用分页或滚动加载)
- 选择性加载数据:在下拉框中选择某个项时再加载相应的数据,而不是在页面加载时一次性加载所有数据。
- 数据异步处理数据:将大数据处理放到 `Web Worker` 中处理,避免阻塞主线程,提高页面的响应速度
- 虚拟化表格数据:使用虚拟化技术(如 react-window 或 react-virtualized),只渲染可见的表格行,提升渲染性能。
一.选择性加载数据:效果图如下(这里使用了vxe组件。页面渲染完毕后,只有点击编辑或表格内容才加载对应下拉数据)
实现代码如下:
<template #operate_content="{ row, $rowIndex }">
<span @click="editRowEvent(row)" class="table-btn">
编辑
</span>
<span @click="copy(row, $rowIndex)" class="table-btn">
复制
</span>
<el-popconfirm confirm-button-text="确定" cancel-button-text="取消" :icon="WarningFilled" width="300"
title="是否确认删除运营负责人" @confirm="deleteItem(row)">
<template #reference>
<span :underline="false" class="table-btn">
删除
</span>
</template>
</el-popconfirm>
</template>
const gridOptions = reactive({
//可编辑的配置
editConfig: {
trigger: 'click',
mode: 'row',
showStatus: true
},
columns: [
{ type: "seq", minWidth: 100, title: '序号', width: 60, slots: { default: 'footer' } },
// { field: 'code', title: 'code', width: 60},
{
field: 'operateInfo', minWidth: 200, title: '运营负责人',
editRender: {}, slots: { edit: 'operateInfo_content' },
// editRender: { name: regionEditRender},
//formatter用来改变页面展示内容,由于对于这种方式,在表格中展示的是value值,有时需要展示其他
formatter({ cellValue }) {
let obj
if (isOneDimensionalArray(cellValue)) {
obj = cellValue.map(item => globelData.value[item])
} else {
obj = (cellValue || []).map((item) => globelData.value[item[2].code])
}
return obj
}
},
{ field: 'country', title: '国家', minWidth: 240, editRender: {}, slots: { edit: 'country_content' } },
{ field: 'productType', title: '产品分类', minWidth: 200, editRender: {}, slots: { edit: 'productType_content' } },
{ field: 'productModel', title: '机型/类别', minWidth: 220, editRender: {}, slots: { edit: 'model_content' } },
{ field: 'operate', title: '操作', minWidth: 200, slots: { default: 'operate_content' } }
],
//实现编辑的方法
const editRowEvent = (row: any) => {
const $grid = xGrid.value
if ($grid) {
//添加编辑效果
$grid.setEditRow(row)
}
}
二.懒加载和分页数据:(这里我参考了懒加载思想,实现了数据一条一条加载展示的效果)
方法一:
const $grid = xGrid.value
if ($grid) {
//newData为表格要渲染的数据
for await (let item of newData) {
await create(item)
}
}
//实现一行一行的展示表格数据
const create = async (params) => {
const $grid = xGrid.value
if ($grid) {
const { row: newRow } = await $grid.insertAt(params, -1)
// console.log(newRow)
return new Promise((resolve) => {
requestAnimationFrame(() => {
resolve(newRow)
})
})
}
}
注释:requestAnimationFrame()
requestAnimationFrame是一种在浏览器中实现动画循环的技术,它通过定时器机制来周期性地调用指定的回调函数,以实现网页动画的效果。与传统的setInterval和setTimeout不同,requestAnimationFrame具有更好的浏览器兼容性、更精确的定时控制和更优秀的性能表现。
使用requestAnimationFrame可以将动画的每一帧绘制操作封装为一个回调函数,并将这个回调函数传递给requestAnimationFrame函数。当浏览器准备进行下一帧绘制时,会自动调用这个回调函数,从而实现了动画的循环。
注意:
- 回调函数的参数是一个时间戳(timestamp),表示当前时间点距离页面加载完成的时间。
- 回调函数的执行时间间隔是不固定的,它由浏览器根据渲染性能和其他因素进行调度。
- 如果在一段时间内没有再次调用requestAnimationFrame,则动画会停止。
- 在浏览器处于非激活状态时,requestAnimationFrame的回调函数不会执行。
- requestAnimationFrame可以用于实现各种类型的动画效果,包括DOM动画、Canvas动画、SVG动画、WebGL动画等。
方法二:
let ind = 0
const datas = xGrid.value?.getTableData().tableData
intervalId.value = setInterval(() => {
if(ind === newData.length - 1){
clearInterval(intervalId.value);
}
datas[ind].loading = false
$grid.loadData(datas)
ind++;
}, 50)