uniApp 实战:setStorageSync 存储与 navigateTo 传递数组对象
本文详细介绍了在uniApp开发中存储和传递数组对象的方法。通过uni.setStorageSync实现本地缓存时,需将数组对象转为JSON字符串存储,读取时再解析回原格式;使用uni.navigateTo页面跳转传参时,需先对数据进行序列化和URL编码。文章提供两种实战方案:直接传参适合小数据量场景;"缓存+标识"方案适用于大数据量传输。关键注意事项包括异常捕获、URL编解码
uniApp 实战:setStorageSync 存储与 navigateTo 传递数组对象
在 uniApp 跨端开发中,数组对象的存储(如缓存用户列表、订单数据)与页面间传递(如列表页跳转详情页携带多条数据)是高频需求。uniApp 提供的 uni.setStorageSync 可实现本地缓存,uni.navigateTo 支持页面跳转传参,但直接传递数组对象会面临格式转换、数据丢失等问题。本文详解数组对象的缓存存储、跨页面传递技巧与避坑指南,附完整实战案例,帮助开发者快速落地功能。
一、核心原理与适用场景
1. 关键技术原理
- uni.setStorageSync 存储限制:本地缓存仅支持存储字符串类型数据,数组对象需通过 JSON.stringify() 转为 JSON 字符串后存储,读取时用 JSON.parse() 解析回原格式;
- uni.navigateTo 传参限制:URL 传参长度有限(通常不超过 2KB),且仅支持字符串 / 数字类型,数组对象需先序列化为 JSON 字符串,接收页再反序列化。
2. 典型应用场景
|
场景 |
技术选择 |
核心价值 |
|
缓存用户收藏列表 |
uni.setStorageSync + JSON 序列化 |
持久化存储,下次打开应用仍可用 |
|
列表页跳转详情页传递多条数据 |
uni.navigateTo + JSON 序列化 |
无需重复请求接口,直接传递完整数据 |
|
跨页面共享临时数组 |
缓存 + 页面传参结合 |
兼顾性能与数据完整性 |
二、实战一:uni.setStorageSync 存储数组对象
1. 核心步骤
- 定义数组对象(如订单列表、商品数据);
- 通过 JSON.stringify() 转为 JSON 字符串;
- 调用 uni.setStorageSync 存储到本地缓存;
- 读取时用 JSON.parse() 解析为原数组对象。
2. 完整代码实现
<template>
<view class="storage-demo">
<button @click="saveArray">存储订单数组</button>
<button @click="readArray" style="margin-top: 20rpx;">读取订单数组</button>
<view class="list" v-if="orderList.length">
<view class="list-item" v-for="(item, index) in orderList" :key="index">
<text>订单号:{{ item.orderNo }}</text>
<text>金额:{{ item.amount }} 元</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
orderList: [] // 存储读取后的订单数组
};
},
methods: {
// 存储数组对象到本地缓存
saveArray() {
// 1. 定义原始数组对象(模拟接口返回数据)
const originalOrders = [
{ orderNo: "LA20240520001", amount: 99, status: "已完成" },
{ orderNo: "LA20240520002", amount: 129, status: "洗护中" },
{ orderNo: "LA20240520003", amount: 69, status: "待接单" }
];
try {
// 2. 序列化:数组对象 → JSON 字符串
const ordersStr = JSON.stringify(originalOrders);
// 3. 存储到本地缓存(key 为自定义标识)
uni.setStorageSync("laundry_orders", ordersStr);
uni.showToast({ title: "存储成功" });
} catch (err) {
console.error("存储失败:", err);
uni.showToast({ title: "存储失败", icon: "none" });
}
},
// 从本地缓存读取数组对象
readArray() {
try {
// 1. 读取缓存的 JSON 字符串
const ordersStr = uni.getStorageSync("laundry_orders");
if (ordersStr) {
// 2. 反序列化:JSON 字符串 → 数组对象
this.orderList = JSON.parse(ordersStr);
uni.showToast({ title: `读取到 ${this.orderList.length} 条订单` });
} else {
uni.showToast({ title: "无缓存数据", icon: "none" });
}
} catch (err) {
console.error("读取失败:", err);
uni.showToast({ title: "读取失败", icon: "none" });
}
}
}
};
</script>
<style scoped>
.storage-demo {
padding: 20rpx;
}
button {
padding: 15rpx;
background-color: #2c3e50;
color: #fff;
border-radius: 8rpx;
}
.list {
margin-top: 30rpx;
}
.list-item {
padding: 20rpx;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
font-size: 28rpx;
}
</style>
3. 关键注意事项
- 异常捕获:存储 / 读取时需用 try-catch 包裹,避免 JSON 格式错误或缓存空间不足导致崩溃;
- 数据类型限制:数组对象中不能包含 Function、Date 等无法序列化的类型(Date 可先转为时间戳存储);
- 缓存上限:本地缓存总容量通常为 10MB,避免存储过大数组对象。
三、实战二:uni.navigateTo 传递数组对象
1. 核心步骤
- 列表页:数组对象 → JSON 字符串 → URL 编码(避免特殊字符导致传参失败);
- 跳转时通过 URL 传递序列化后的字符串;
- 详情页:接收 URL 参数 → URL 解码 → JSON 解析 → 还原数组对象。

2. 列表页(传参方)代码
<template>
<view class="list-page">
<view class="list-item" v-for="(item, index) in orderList" :key="index" @click="goToDetail(item)">
<text>订单号:{{ item.orderNo }}</text>
<text>状态:{{ item.status }}</text>
<uni-icons type="right" color="#ccc"></uni-icons>
</view>
</view>
</template>
<script>
export default {
data() {
return {
orderList: [
{ orderNo: "LA20240520001", amount: 99, status: "已完成", items: ["衬衫", "裤子"] },
{ orderNo: "LA20240520002", amount: 129, status: "洗护中", items: ["外套", "毛衣"] },
{ orderNo: "LA20240520003", amount: 69, status: "待接单", items: ["T恤", "袜子"] }
]
};
},
methods: {
goToDetail(order) {
try {
// 1. 序列化数组对象(此处单条订单对象,多条同理)
const orderStr = JSON.stringify(order);
// 2. URL 编码:解决特殊字符(如引号、空格)导致的传参失败
const encodeOrder = encodeURIComponent(orderStr);
// 3. 跳转页面并传递参数
uni.navigateTo({
url: `/pages/detail/detail?order=${encodeOrder}`
});
} catch (err) {
console.error("传参失败:", err);
uni.showToast({ title: "跳转失败", icon: "none" });
}
}
}
};
</script>
<style scoped>
.list-page {
padding: 20rpx;
}
.list-item {
padding: 20rpx;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
}
</style>
3. 详情页(接收方)代码
<template>
<view class="detail-page">
<view class="detail-item">
<text class="label">订单号:</text>
<text class="value">{{ orderInfo.orderNo }}</text>
</view>
<view class="detail-item">
<text class="label">金额:</text>
<text class="value">{{ orderInfo.amount }} 元</text>
</view>
<view class="detail-item">
<text class="label">状态:</text>
<text class="value">{{ orderInfo.status }}</text>
</view>
<view class="detail-item">
<text class="label">洗护物品:</text>
<text class="value">{{ orderInfo.items.join("、") }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
orderInfo: {} // 接收后的订单详情
};
},
onLoad(options) {
// 页面加载时接收参数
this.getOrderData(options);
},
methods: {
getOrderData(options) {
try {
// 1. 接收 URL 参数并解码
const decodeOrder = decodeURIComponent(options.order);
// 2. 反序列化:JSON 字符串 → 数组对象
this.orderInfo = JSON.parse(decodeOrder);
} catch (err) {
console.error("解析参数失败:", err);
uni.showToast({ title: "数据加载失败", icon: "none" });
}
}
}
};
</script>
<style scoped>
.detail-page {
padding: 30rpx;
}
.detail-item {
margin-bottom: 30rpx;
font-size: 28rpx;
display: flex;
flex-direction: column;
}
.label {
color: #666;
margin-bottom: 10rpx;
font-size: 26rpx;
}
.value {
color: #333;
font-weight: 500;
}
</style>
四、进阶方案:缓存 + 传参结合(大数据量场景)
当数组对象较大(超过 2KB)时,直接通过 navigateTo 传参会导致数据截断,推荐采用 “缓存存储 + 传参标识” 方案:
1. 核心逻辑
- 列表页:将数组对象存储到本地缓存,生成唯一标识(如时间戳);
- 跳转时仅传递标识,不传递完整数据;
- 详情页:通过标识读取本地缓存中的数组对象。
2. 代码示例(列表页)
goToDetail(orderList) {
try {
// 1. 生成唯一标识(避免缓存覆盖)
const cacheKey = "order_list_" + Date.now();
// 2. 存储数组对象到缓存
uni.setStorageSync(cacheKey, JSON.stringify(orderList));
// 3. 跳转时仅传递缓存标识
uni.navigateTo({
url: `/pages/detail/detail?cacheKey=${cacheKey}`
});
} catch (err) {
console.error("跳转失败:", err);
}
}
3. 代码示例(详情页)
onLoad(options) {
const cacheKey = options.cacheKey;
// 读取缓存中的数组对象
const orderListStr = uni.getStorageSync(cacheKey);
const orderList = JSON.parse(orderListStr);
// 按需清理缓存(可选,避免占用空间)
uni.removeStorageSync(cacheKey);
}
五、关键优化与避坑指南
1. 核心优化点
- URL 编码解码:必须使用 encodeURIComponent/decodeURIComponent 处理 JSON 字符串,避免引号、斜杠等特殊字符导致传参失败;
- 数据清理:临时缓存的数据的在使用后通过 uni.removeStorageSync 清理,避免占用缓存空间;
- 类型校验:解析后通过 typeof 或 Array.isArray 校验数据类型,防止解析失败导致页面报错。
2. 常见问题与解决方案
|
问题现象 |
原因分析 |
解决方案 |
|
传参后解析为 null |
JSON 字符串格式错误或 URL 编码遗漏 |
确保序列化后无语法错误,传参前执行 URL 编码 |
|
数据截断 / 丢失 |
数组对象过大,超过 URL 传参限制 |
采用 “缓存 + 标识” 方案,避免直接传大数据 |
|
缓存覆盖 |
多个数组对象使用相同缓存 key |
用时间戳、唯一 ID 生成动态 key |
|
解析失败(Date 类型) |
Date 对象无法被 JSON 序列化 |
先将 Date 转为时间戳或字符串,解析后还原 |
六、多端适配注意事项
- App 端:本地缓存容量较大(通常 10-50MB),支持存储较大数组对象;
- 微信小程序:缓存容量限制为 10MB,且 URL 传参长度限制更严格(建议不超过 1KB);
- H5 端:缓存受浏览器限制,且跨域跳转时缓存不可共享,需谨慎使用。
总结
uniApp 中存储与传递数组对象的核心是 “JSON 序列化与反序列化”,uni.setStorageSync 负责持久化存储,uni.navigateTo 结合 URL 编码实现跨页面传递。简单场景可直接序列化传参,大数据量场景推荐 “缓存 + 标识” 方案,兼顾性能与数据完整性。实际开发中需注意异常捕获、特殊字符处理与多端适配,避免出现数据丢失、解析失败等问题。掌握该技巧可高效解决跨页面数据共享需求,提升应用开发效率与用户体验。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)