在微信小程序中渲染数据时通常会使用setData方法,但是setData对数据是有影响的,单次设置的数据不能超过1024kB,否则就会出现卡顿甚至有时会导致小程序闪退等现象。而我们平时在实现业务时,一般会采取数据分页而防止大量数据渲染导致小程序白屏/卡顿,例如在一些商城平台需要滚动时切换菜单,也需要回显购物车数据的情况下,无法进行分页处理,我的方法是把从接口获取到的数据进行格式化处理后,进行递归调用(递归一次进行一次setDate从而不进行一次性渲染大量数据),代码如下:文章来源:https://uudwc.com/A/rZAGv
<template>
<scroll-box>
<!-- 菜单 -->
<view>
<view v-for="(item,index) in truthfulData" :key="item.id">
{{item.title}}
</view>
</view>
<!-- 子列表 -->
<view>
<!-- 菜单 -->
<view v-for="(item,index) in truthfulData" :key="item.id">
{{item.title}}
</view>
<view>
<!-- 子列表 -->
<view v-for="(childItem,childIndex) in itme.childList" :key="childItem.id">
{{childItem.name}}
</view>
</view>
</view>
</scroll-box>
</template>
<script setup lang="ts">
// 获取数据列表
const truthfulData = ref(null) // 真实渲染数据
// 处理数据模型 [{id,title,childList:[]},{id,title,childList:[]}...]
async function getDate() {
try {
// 1. 通过接口调用获取需要渲染的数据列表
const dateList= await getDateList()
// 2. 调用setDate优化函数
truthfulData.value = []
injectDate(dateList.data,0,0)
// 3. 进行渲染完成后的容器数据获取 - 小程序 uni.createSelectorQuery().select("#id").boundingClientRect(data=>{...}).exec() 是异步方法需要在数据渲染后执行
nextTick(() => {
// ...
})
} catch (e) {
console.log(e);
}
}
// 优化渲染数据
function injectDate(virtuallyDate : [any], pIndex : number, index : number) {
if (virtuallyDate.length === pIndex) return
// 当菜单数据为空时
if (!truthfulData.value[pIndex]) {
// 数据最外层菜单赋值
truthfulData.value[pIndex] = {
id: virtuallyDate[pIndex].id,
title: virtuallyDate[pIndex].title,
childList: [] // 需要渲染的子集数据
}
}
// 添加数据
truthfulData.value[pIndex].childList.push(...virtuallyDate[pIndex].childList.slice(index, index + 20)) // 20 根据自己的数据大小拟定
let i = index + 20
if (i >= virtuallyDate[pIndex].childList.length) i = 0
initCommodityList(virtuallyDate , i === 0 ? pIndex + 1 : pIndex, i) // 递归调用
}
</script>
递归setDate 渲染之后可用正常获取容器的宽高进行进一步业务扩展
大致效果如下:
建议搭配图片懒加载使用,防止大量图片同时请求导致服务器承受不住文章来源地址https://uudwc.com/A/rZAGv