news 2026/6/15 17:54:55

【小程序】订单数据缓存 以及针对海量库存数据的 懒加载+数据分片 的具体实现方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【小程序】订单数据缓存 以及针对海量库存数据的 懒加载+数据分片 的具体实现方式

订单数据缓存以及针对海量库存数据的懒加载+数据分片的具体实现方式,结合UniApp+微信小程序的技术栈,分两部分详细拆解落地思路和核心代码,既讲逻辑也给可落地的实现方案。

一、订单数据缓存的实现(低网环境适配核心)

业务背景

汽配商户常处于仓库等低网/断网环境,开单过程中如果网络中断,已填写的订单数据不能丢失;网络恢复后需自动同步,因此缓存核心是「本地持久化+合理的同步策略」。

实现思路&核心代码

我基于微信小程序的本地存储API(wx.setStorageSync/wx.getStorageSync)封装了缓存工具类,结合「临时缓存+持久缓存+过期策略」实现,具体步骤如下:

1. 第一步:设计缓存策略
缓存类型适用场景存储位置过期策略
临时缓存订单草稿(未提交)微信临时缓存小程序退出后自动清理
持久缓存已提交待同步的订单微信本地持久存储同步成功后删除,7天过期
2. 第二步:封装通用缓存工具类(核心复用)
// utils/cache.ts - 统一管理缓存逻辑/** * 订单数据缓存工具类 * @param key 缓存键名(区分不同订单:order_draft_+开单员ID+时间戳) * @param data 要缓存的订单数据 * @param isPersistent 是否持久缓存(默认临时) */exportconstorderCache={// 设置缓存set:(key:string,data:any,isPersistent=false)=>{constcacheData={data,timestamp:Date.now(),// 记录缓存时间,用于过期判断isPersistent// 标记是否持久缓存};// 临时缓存用wx.setStorage(异步),持久缓存用同步存储(确保数据落地)if(isPersistent){wx.setStorageSync(`persist_${key}`,JSON.stringify(cacheData));}else{wx.setStorage({key:`temp_${key}`,data:JSON.stringify(cacheData),fail:()=>{console.error('订单缓存失败,低网环境请注意手动保存');}});}},// 获取缓存get:(key:string,isPersistent=false)=>{constcacheKey=isPersistent?`persist_${key}`:`temp_${key}`;constcacheStr=isPersistent?wx.getStorageSync(cacheKey):wx.getStorageSync(cacheKey);if(!cacheStr)returnnull;constcacheData=JSON.parse(cacheStr);// 过期判断:持久缓存7天过期(604800000ms),临时缓存无过期但小程序退出失效if(isPersistent&&(Date.now()-cacheData.timestamp)>604800000){this.remove(key,isPersistent);// 清理过期缓存returnnull;}returncacheData.data;},// 删除缓存(同步成功后调用)remove:(key:string,isPersistent=false)=>{constcacheKey=isPersistent?`persist_${key}`:`temp_${key}`;wx.removeStorageSync(cacheKey);},// 同步缓存订单到后端(网络恢复时触发)syncCacheOrder:async(key:string)=>{constcacheOrder=this.get(key,true);if(!cacheOrder)return;try{// 调用后端同步接口constres=awaituni.request({url:'/api/order/sync',method:'POST',data:cacheOrder});if(res.data.code===200){this.remove(key,true);// 同步成功,删除缓存uni.showToast({title:'订单同步成功'});}}catch(err){console.error('订单同步失败,保留缓存:',err);}}};
3. 第三步:业务层集成(开单页面)

在开单页面的输入、选择配件等操作时,实时缓存数据;页面初始化时先读取缓存,避免数据丢失:

<!-- pages/order/create.vue --> <script setup lang="ts"> import { orderCache } from '@/utils/cache'; import { ref, onMounted, onUnload } from 'vue'; // 订单唯一标识(开单员ID+当前时间戳) const orderKey = `order_draft_${uni.getStorageSync('userId')}_${Date.now()}`; // 订单表单数据 const orderForm = ref({ partsList: [], // 配件列表 customerInfo: {}, // 客户信息 totalAmount: 0, // 总金额 status: 'draft' // 草稿状态 }); // 页面初始化:读取缓存的订单草稿 onMounted(() => { const cacheData = orderCache.get(orderKey); if (cacheData) { orderForm.value = cacheData; // 恢复缓存的草稿数据 uni.showToast({ title: '恢复离线草稿数据' }); } // 监听网络状态,恢复网络时自动同步持久缓存的订单 wx.onNetworkStatusChange((res) => { if (res.isConnected) { orderCache.syncCacheOrder(orderKey); } }); }); // 输入框/选择器变化时,实时缓存 const handleFormChange = () => { orderCache.set(orderKey, orderForm.value); }; // 提交订单:转为持久缓存(待同步) const submitOrder = () => { if (!uni.getNetworkType().networkType === 'none') { // 断网:持久缓存,标记待同步 orderCache.set(orderKey, orderForm.value, true); uni.showToast({ title: '断网已保存,恢复网络后自动提交' }); } else { // 有网:直接提交接口 // ... 接口请求逻辑 } }; </script>
核心要点
  • JSON.stringify/parse处理本地存储的序列化(小程序本地存储仅支持字符串);
  • 区分临时/持久缓存,避免无效数据占用存储;
  • 监听网络状态(wx.onNetworkStatusChange),实现断网缓存、联网自动同步。

二、库存数据懒加载+数据分片的实现(性能优化核心)

业务背景

库存数据量极大(49448品种/29728数量),一次性加载所有数据会导致页面卡顿、内存溢出,因此采用「后端分页(数据分片)+ 前端滚动懒加载」的方案,仅加载当前可视区域数据。

实现思路&核心代码
1. 第一步:后端接口改造(数据分片)

后端提供分页接口,接收pageNum(页码)、pageSize(每页条数)参数,返回「当前页数据+总条数」,示例返回格式:

{"code":200,"data":{"list":[/* 每页库存数据 */],"total":49448,// 总条数"pageNum":1,"pageSize":20}}
2. 第二步:前端懒加载实现(滚动加载下一页)

基于UniApp的onReachBottom(页面触底)生命周期,结合分页状态管理,实现滚动加载:

<!-- pages/stock/list.vue --> <script setup lang="ts"> import { ref, onMounted, onReachBottom } from 'vue'; import { getStockList } from '@/api/stock'; // 库存列表接口 // 分页参数 const pageParams = ref({ pageNum: 1, pageSize: 20, total: 0, // 总条数 loading: false, // 加载中状态(防止重复请求) finished: false // 加载完成(无更多数据) }); // 库存列表数据(仅存储已加载的分片数据) const stockList = ref([]); // 加载库存数据(分片请求) const loadStockData = async () => { if (pageParams.value.loading || pageParams.value.finished) return; pageParams.value.loading = true; try { const res = await getStockList({ pageNum: pageParams.value.pageNum, pageSize: pageParams.value.pageSize }); // 拼接当前页数据(分片加载) stockList.value = [...stockList.value, ...res.data.list]; // 更新分页状态 pageParams.value.total = res.data.total; // 判断是否加载完成(无更多数据) if (stockList.value.length >= pageParams.value.total) { pageParams.value.finished = true; } else { pageParams.value.pageNum += 1; // 页码+1,准备加载下一页 } } catch (err) { console.error('库存数据加载失败:', err); } finally { pageParams.value.loading = false; } }; // 页面初始化:加载第一页 onMounted(() => { loadStockData(); }); // 页面触底:加载下一页(懒加载核心) onReachBottom(() => { loadStockData(); }); </script> <template> <view class="stock-list"> <!-- 库存列表:仅渲染已加载的分片数据 --> <uni-list v-for="(item, index) in stockList" :key="index"> <uni-list-item title="{{item.partName}}" note="库存数量:{{item.stockNum}}" show-arrow /> </uni-list> <!-- 加载状态提示 --> <view v-if="pageParams.loading" class="loading">加载中...</view> <view v-if="pageParams.finished" class="finished">已加载全部库存</view> </view> </template>
额外优化(可选):可视区域渲染

如果单页加载20条仍有卡顿,可结合uni-virtual-list(虚拟列表),仅渲染当前屏幕可视区域的库存项,进一步降低DOM渲染压力:

<!-- 虚拟列表替代普通列表,仅渲染可视区域 --> <uni-virtual-list :height="800" // 列表高度 :item-height="80" // 每项高度 :list="stockList" // 数据源 > <template v-slot:item="{ item }"> <uni-list-item title="{{item.partName}}" note="库存数量:{{item.stockNum}}" /> </template> </uni-virtual-list>
核心要点
  • loading状态防止「触底重复请求」,用finished状态标记「无更多数据」;
  • 数据分片核心是「后端分页+前端分批请求」,仅加载当前页数据;
  • 懒加载核心是「监听页面触底事件」,动态拼接数据,避免一次性渲染海量DOM。

总结

  1. 订单数据缓存:核心是「微信小程序本地存储+缓存策略」,区分临时/持久缓存,监听网络状态实现断网缓存、联网同步,保障低网环境操作流畅;
  2. 库存懒加载+数据分片:核心是「后端分页(数据分片)+ 前端触底懒加载」,结合loading/finished状态控制请求,可选虚拟列表进一步优化渲染性能,解决海量数据加载卡顿问题。

这两个方案既贴合UniApp+微信小程序的技术栈特性,也能在简历/面试中体现你对「性能优化」「边界场景(低网)」的思考,是汽配小程序这类ToB业务的核心优化点。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 23:51:53

深度学习毕设项目:基于python-CNN卷积神经网络对海洋壳类生物识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/14 18:13:48

别急着写 DFS:聊聊《二叉树的所有路径》背后那些容易被忽略的事

别急着写 DFS:聊聊《二叉树的所有路径》背后那些容易被忽略的事 作者|Echo_Wish 一、引子:这道题,真有那么“简单”吗? 如果你刷过 LeetCode,那你大概率见过这道题—— Binary Tree Paths(二叉树的所有路径)。 题目一句话就说完了: 给你一棵二叉树,返回从根节点到…

作者头像 李华
网站建设 2026/6/10 15:58:05

手把手教你:提示工程架构师如何做竞品功能调研?(附分析模板)

手把手教你:提示工程架构师如何做竞品功能调研?(附可复用分析模板) 引言:你做的竞品调研,可能只是“看个热闹” 作为提示工程(Prompt Engineering)架构师,你一定遇到过这样的场景: 产品经理拍着桌子问:“竞品出了个Prompt模板库,我们要不要跟进?” 开发同学皱着…

作者头像 李华
网站建设 2026/6/4 22:07:53

**免费有声书配音软件2025推荐,解锁个人声音变现新路径*

免费有声书配音软件2025解析&#xff0c;解锁个人声音变现新路径在内容创作与知识付费浪潮的推动下&#xff0c;有声书市场正迎来前所未有的增长。据《2025中国数字阅读与有声内容产业报告》显示&#xff0c;2025年国内有声书市场规模预计突破120亿元&#xff0c;用户规模超5.8…

作者头像 李华
网站建设 2026/6/15 13:36:54

为什么AI算法工程师年薪能破百万?大厂高薪岗位学习指南与实战经验分享_月薪35-50k 16薪

大模型算法工程师成为当前薪资最高的技术岗位&#xff0c;月薪中位数近3万元&#xff0c;顶尖人才年薪破百万。字节、腾讯等大厂大量扩招AI人才&#xff0c;DeepSeek等开出高达154万年薪。然而多数求职者能力不足以满足企业需求。《AI算法工程师培养计划》由一线大厂专家主讲&a…

作者头像 李华