
简体中文
app、小程序、web,均提供了方便的key-value模式的本地数据存储,通过键值对的方式存取数据。
uni-app的Storage在不同端的实现不同:
Android
端采用应用内SQLite数据库储存,储存位置为:/data/data/io.dcloud.uniappx(基座包名)/databases/DCStorage。注意
uni-
、uni_
、dcloud-
、dcloud_
为前缀的key,为系统保留关键前缀。如uni_deviceId
、uni_id_token
,请开发者为key命名时避开这些前缀。uni.setStorage函数定义 将数据存储在本地storage存储中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | SetStorageOptions | 是 | - | - | |||||||||||||||||||||||||||||||||||||
|
uni.setStorageSync函数定义 将 data 存储在本地storage存储中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
key | string | 是 | - | - | 本地storage存储中的指定的 key |
data | any | 是 | - | - | 需要存储的内容,只支持能通过 JSON.stringify 序列化的对象 |
WARNING
参数 data
为对象字面量时,需要通过 as UTSJSONObject
明确类型,例如:
uni.setStorageSync('obj', {"a": 1} as UTSJSONObject)
uni.getStorage函数定义 从本地存储中异步获取指定 key 对应的内容。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | GetStorageOptions | 是 | - | - | |||||||||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
data | any | 否 | - | - | key 对应的内容 |
注意:
getStorageSync的返回值类型为any。因为set的时候任意类型都可以set进去。
使用any类型的数据需要as为正确的类型,才能调用类型上的方法。
对于简单类型,如string,只需要 as string。但对于复杂类型,比如 UTSJSONObject、type、class,需要参考获取复杂类型的数据章节,见下
注意:获取一个不存在的 key 会触发 fail 回调,返回错误信息为 "getStorage:fail data not found" 的错误。
uni.getStorageSync函数定义 从本地存储中同步获取指定 key 对应的内容。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
key | string | 是 | - | - | 本地存储中的指定的 key |
类型 | 必备 |
---|---|
any | 否 |
注意:
getStorageSync的返回值类型为any。因为set的时候任意类型都可以set进去。
使用any类型的数据需要as为正确的类型,才能调用类型上的方法。
对于简单类型,如string,只需要 as string。但对于复杂类型,比如 UTSJSONObject、type、class,需要参考获取复杂类型的数据章节,见下
另注意,同步方法获取一个不存在的 key 会返回空字符串,而不是 null。如需准确判断是空字符串还是null,应该使用异步方法uni.getStorage
。
获取较大量的数据时,也推荐使用异步方法uni.getStorage
,避免同步阻塞。
uni.getStorageInfo函数定义 异步获取当前 storage 的相关信息。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | GetStorageInfoOptions | 是 | - | - | |||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
keys | Array<string> | 是 | - | 当前 storage 中所有的 key | |
currentSize | number | 是 | - | 当前占用的空间大小, 单位:kb | |
limitSize | number | 是 | - | 限制的空间大小, 单位:kb |
uni.getStorageInfoSync函数定义 同步获取当前 storage 的相关信息。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
类型 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
GetStorageInfoSuccess | uni.getStorageInfo成功回调参数 | ||||||||||||||||||||||||
|
uni.removeStorage函数定义 从本地存储中异步移除指定 key。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options | RemoveStorageOptions | 是 | - | - | |||||||||||||||||||||||||||||||
|
uni.removeStorageSync函数定义 从本地存储中同步移除指定 key。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
key | string | 是 | - | - | 本地存储中的指定的 key |
uni.clearStorage函数定义 清除本地数据存储。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
option | ClearStorageOptions | 否 | - | - | uni.removeStorage参数定义 | ||||||||||||||||||||||||
|
uni.clearStorageSync函数定义 清除本地数据存储。
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
4.0 | 4.41 | 3.9.0 | 4.11 | 4.61 |
Template
Script
<template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view>
<page-head :title="title"></page-head>
<view class="uni-common-mt">
<view class="uni-list">
<view class="uni-list-cell uni-list-cell-line">
<view class="uni-list-cell-left">
<view class="uni-label">key</view>
</view>
<view class="uni-list-cell-db">
<input class="uni-input" type="text" placeholder="请输入key" name="key" :value="key" maxlength="-1"
@input="keyChange" />
</view>
</view>
<view class="uni-list-cell">
<view class="uni-list-cell-left">
<view class="uni-label">value</view>
</view>
<view class="uni-list-cell-db">
<input class="uni-input" type="text" placeholder="请输入value" name="data"
:value="typeof data === 'string' ? data : JSON.stringify(data)" maxlength="-1" @input="dataChange" />
</view>
</view>
</view>
<view class="uni-padding-wrap">
<view class="uni-btn-v">
<button class="uni-btn btn-getStorageInfoASync" type="primary" @tap="getStorageInfo">
获取存储概述信息-异步
</button>
<button class="uni-btn btn-getStorageInfoSync" @tap="getStorageInfoSync">
获取存储概述信息-同步
</button>
</view>
<text>{{ storageInfo }}</text>
<view class="uni-flex uni-row">
<button type="default" style="width:50%" @tap="strMock">
填充字符串
</button>
<button type="default" style="width:50%" @tap="complexMock">
填充复杂对象
</button>
</view>
<view class="uni-flex uni-row">
<button type="default" style="width:50%" @tap="numberMock">
填充整型
</button>
<button type="default" style="width:50%" @tap="floatMock">
填充浮点型
</button>
</view>
<view class="uni-flex uni-row">
<button type="default" style="width:50%" @tap="jsonLikeMock">
填充json字符串
</button>
<button type="default" style="width:50%" @tap="longLikeMock">
填充整数字符串
</button>
</view>
<view class="uni-flex uni-row">
<button type="default" style="width:50%" @tap="floatLikeMock">
填充浮点字符串
</button>
<button type="default" style="width:50%" @tap="negativeLikeMock">
填充负数字符串
</button>
</view>
<view class="uni-flex uni-row">
<button type="default" class="uni-btn btn-complexStaticTest" style="width:100%" @tap="complexStaticTest">
字面量读写测试
</button>
</view>
</view>
<view class="uni-padding-wrap">
<view class="uni-btn-v">
<button type="primary" class="uni-btn btn-setstorageAsync" @tap="setStorage">
存储数据-异步
</button>
<button class="uni-btn btn-getstorageAsync" @tap="getStorage">读取数据-异步</button>
<button class="uni-btn btn-removeStorageInfoASync" @tap="removeStorage">移除数据-异步</button>
<button class="uni-btn btn-clearStorageInfoASync" @tap="clearStorage">清理数据-异步</button>
</view>
<view class="uni-btn-v">
<button type="primary" class="uni-btn btn-setstorageSync" @tap="setStorageSync">
存储数据-同步
</button>
<button class="uni-btn btn-getstorageSync" @tap="getStorageSync">读取数据-同步</button>
<button class="uni-btn btn-removeStorageInfoSync" @tap="removeStorageSync">
移除数据-同步
</button>
<button class="uni-btn btn-clearStorageInfoSync" @tap="clearStorageSync">
清理数据-同步
</button>
</view>
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<style>
</style>
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
errMsg | string | 是 | - | 错误信息 |
首先明确一个原则,Storage实际储存到各终端文件系统的是序列化后的数据。
也就是当我们使用setStorage/setStorageSync 储存一个带类型的数据时,插件内部会自动将其序列化为字符串后进行储存。当我们调用 getStorage/getStorageSync 插件内部也会尝试对字符串进行类型还原,分为以下几种情况:
如果是UTSJSONObject
类型,不会有类型的丢失
let json1 = {
id:1001,
name:"jack"
}
uni.setStorageSync("test-json",json1)
let json2 = uni.getStorageSync("test-json")
// json2 [UTSJSONObject] {id: 1001, name: "jack"}
console.log("json2",json2)
如果是type类型,可以正常写入,但是当读取时得到是是UTSJSONObject类型,需要进行类型转换。
type User = {
name:string,
age:number
}
let u1 = {
name : "张三",
age:123
}
uni.setStorageSync("test-a",u1)
uni.getStorage({
key:'test-a',
success:function(res:GetStorageSuccess){
// 此时只能得到的UTSJSONObject类型
let jsonObject = res.data
// 再次进行类型转换
let userObject = JSON.parse<User>(JSON.stringify(jsonObject))
// jsonObject [UTSJSONObject] {age: 123, name: "张三"}
console.log("jsonObject",jsonObject)
// userObject [User] {age: 123, name: "张三"}
console.log("userObject",userObject)
}
})
还有一种情况,如果开发者使用class而非type定义类型,默认情况下无法读写的。
大多数情况下,我们更推荐使用type,而不是自定义class。 因为自定义class的行为在不同终端可能表现不一致。
class Person {
// 声明属性类型(必须显式初始化或在构造函数中赋值)
name: string;
age: number;
// 构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 方法
greet(): string {
return `Hello, I'm ${this.name} and I'm ${this.age} years old.`;
}
}
// 使用类
const alice = new Person("Alice", 30);
console.log(alice.greet()); // "Hello, I'm Alice and I'm 30 years old."
uni.setStorageSync("test-class-0",alice)
let dataObj = uni.getStorageSync("test-class-0")
// 此时只能得到空的UTSJSONObject {}
console.log("data",dataObj)
如果要支持读写,开发者需要实现 IJSONStringify
接口。关于IJSONStringify的更多介绍
class Person implements IJSONStringify {
// 声明属性类型(必须显式初始化或在构造函数中赋值)
name: string;
age: number;
// 构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 自定义序列化规则
toJSON():any{
let jsonRet = UTSJSONObject()
jsonRet["name"] = this.name
jsonRet["age"] = this.age
return jsonRet
}
// 方法
greet(): string {
return `Hello, I'm ${this.name} and I'm ${this.age} years old.`;
}
}
// 使用类
const alice = new Person("Alice", 30);
console.log(alice.greet()); // "Hello, I'm Alice and I'm 30 years old."
uni.setStorageSync("test-class-0",alice)
let dataObj = uni.getStorageSync("test-class-0")
// [UTSJSONObject] {name: "Alice", age: 30}
console.log("dataObj",dataObj)
// [Person] {age: 30, name: "Alice"}
let personObj = JSON.parse<Person>(JSON.stringify(dataObj))
console.log("personObj",personObj)
此时,我们就可以让自定义class实现类似自定义type的效果了。