以下是 UniApp 离线本地存储方案的详细介绍及推荐方案分析:
一、UniApp 离线本地存储方案分类
1. 基于 uni.storage
系列 API(跨端基础方案)
- API 及特点:
- 提供
uni.setStorage
(异步存储)、uni.getStorage
(异步读取)、uni.removeStorage
(异步移除) ,以及同步版本uni.setStorageSync
、uni.getStorageSync
、uni.removeStorageSync
、uni.clearStorageSync
(清空存储)。 - 不同端有不同映射:
- H5 端:映射为
localStorage
,受浏览器限制,一般单域名下存储大小约 5M ,属于缓存性质,可能因浏览器策略(如清理缓存)被清除 。 - App 端:映射为
plus.storage
(5+App 提供),无官方明确大小限制(实际受设备存储容量影响),是持久化存储,不会因应用重启等丢失数据 。 - 小程序端:映射为各小程序平台自身的存储 API(如微信小程序
wx.setStorage
等 ),不同平台有容量限制(如微信小程序单 key 最大 1MB、总上限 10MB ),数据生命周期与小程序一致,除非主动删除或超期清理。
- H5 端:映射为
- 提供
- 适用场景:存储简单键值对数据,像用户登录态标识、简单配置项(如主题选择)、少量离线缓存的业务数据(如用户收藏的简短 ID 列表 )。例如存储用户是否已阅读引导页的标记,用
uni.setStorageSync('hasReadGuide', true)
记录。
2. 文件系统存储(plus.io
,主要用于 App 端 )
- 原理与能力:通过 5+App 的
plus.io
模块操作本地文件系统,可实现文件的创建、读写、删除、遍历等。能将数据以文件形式(如文本文件、二进制文件)存储在设备本地指定目录。 - 适用场景:
- 存储较大体积数据,比如离线的图文内容(将文章内容存为
.txt
文件、图片存为本地文件 )。例如新闻类 App 离线缓存多篇文章,把文章文本存成文件,用plus.io
管理文件路径和读写。 - 需灵活组织数据结构,或要与原生系统文件交互的场景。比如 App 需缓存一批本地可执行的脚本文件、自定义格式的配置包等。
- 存储较大体积数据,比如离线的图文内容(将文章内容存为
- 示例代码(App 端):
// 写入文本内容到本地文件
function writeFile(content) {
const path = '_doc/test.txt'; // 本地存储路径,_doc 是 5+App 可读写目录
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(path, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.write(content);
console.log('文件写入成功');
}, function(err) {
console.error('写入失败:', err);
});
}, function(err) {
console.error('获取文件入口失败:', err);
});
}, function(err) {
console.error('请求文件系统失败:', err);
});
}
3. 数据库存储(SQLite ,主要用于 App 端 )
- 实现方式:借助
plus.sqlite
模块(5+App 提供),对原生 SQLite 数据库进行封装,可执行 SQL 语句实现数据的增删改查。也可结合一些数据库 ORM 框架(如sqlite ORM
类库,需自行适配 UniApp )简化操作。 - 适用场景:
- 需存储结构化数据,且数据量较大、有复杂查询需求。比如离线存储电商 App 的商品列表(包含商品 ID、名称、价格、库存等字段 ),可通过 SQL 语句快速筛选出某分类下商品。
- 数据需要预置到 App 中(可将数据库文件打包进 App ,安装后直接使用 ),或者要保证数据在设备空间紧张时更稳定(相比
websql
等,系统清理存储时SQLite
数据更不容易被清除 )。
- 示例代码(App 端):
// 打开数据库(不存在则创建)
plus.sqlite.openDatabase({
name: 'test.db',
path: '_doc/test.db',
success: function() {
console.log('数据库打开成功');
// 创建表
plus.sqlite.executeSql({
name: 'test.db',
sql: 'CREATE TABLE IF NOT EXISTS goods (id INTEGER PRIMARY KEY, name TEXT, price REAL)',
success: function() {
console.log('表创建成功');
},
fail: function(err) {
console.error('创建表失败:', err);
}
});
},
fail: function(err) {
console.error('打开数据库失败:', err);
}
});
4. 其他 H5 兼容方案(H5 端专属,App/小程序端慎用 )
sessionStorage
:和localStorage
类似,但存储数据仅在当前会话(页面关闭即清除 ),UniApp H5 端可使用,适用于临时存储会话级数据,如页面跳转间传递的临时标识 。IndexedDB
:H5 端支持的较复杂本地数据库,适合存储大量、复杂结构化数据(如离线的用户行为日志库 ),但手机端系统兼容性欠佳(Android 4.4+、iOS 8+ 才支持 ),且 UniApp 非 H5 端基本不支持,跨端场景下局限性大。websql
:H5 端的关系型数据库方案,不过 iOS 8、9 的wkWebview
不支持,若要用需切换uiwebview
内核(会损失部分性能和特性 ),现在逐渐被IndexedDB
替代,UniApp 中较少推荐使用。
二、推荐方案及选择建议
1. 优先推荐方案:uni.storage
系列 API
- 优势:
- 跨端一致性好:一套 API 适配 H5、App、小程序多端,开发时无需为不同端大量改写存储逻辑 。
- 使用简单:异步和同步方法灵活选择,满足不同代码执行流程需求(简单场景用同步,避免阻塞则用异步 )。
- 覆盖常见轻量存储场景:对于大部分 App 的配置信息、用户标识、少量业务缓存等需求,能简洁高效实现。
- 不足与应对:存储大容量、复杂结构数据能力弱。若有此类需求,结合文件系统存储(App 端用
plus.io
)或数据库存储(App 端用plus.sqlite
)补充即可 。
2. 补充方案选择(针对特殊需求 )
- 需存储大文件/复杂文件结构:选 文件系统存储(
plus.io
) ,手动管理文件读写和路径,适合 App 端离线缓存图片、音频、多文本组合数据等场景 。 - 需存储结构化大数据、有复杂查询:选 SQLite 数据库存储(
plus.sqlite
) ,用 SQL 语句灵活操作数据,适合 App 端的离线业务数据库场景(如本地商品库、离线订单库 ) 。 - 仅 H5 端特殊需求:可考虑
IndexedDB
(处理 H5 端大量结构化数据 ),但要做好兼容性降级处理,且别期望在 App/小程序端复用 。
综上,日常 UniApp 开发中,优先用 uni.storage
系列 API 满足大部分离线存储需求;遇到 App 端大文件、复杂结构化数据等特殊场景,再补充文件系统或 SQLite 数据库存储方案 。