uni-app数据存储全攻略:从本地存储到持久化方案 0 次阅读

数据存储是应用开发中的重要环节,选择合适的存储方案对提升用户体验至关重要。本文将详细介绍uni-app中的数据存储最佳实践。

1. 本地存储基础

1.1 Storage API封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// utils/storage.js
class Storage {
// 设置存储
static set(key, value, expired = 0) {
const data = {
value,
expired: expired ? Date.now() + expired * 1000 : 0
}
uni.setStorageSync(key, JSON.stringify(data))
}

// 获取存储
static get(key) {
const data = uni.getStorageSync(key)
if (!data) return null

const { value, expired } = JSON.parse(data)
// 判断是否过期
if (expired && expired < Date.now()) {
uni.removeStorageSync(key)
return null
}
return value
}

// 移除存储
static remove(key) {
uni.removeStorageSync(key)
}

// 清空存储
static clear() {
uni.clearStorageSync()
}
}

export default Storage

1.2 使用示例

1
2
3
4
5
6
7
8
9
10
11
// 存储数据(7天过期)
Storage.set('userInfo', { name: 'Tom', age: 18 }, 7 * 24 * 60 * 60)

// 获取数据
const userInfo = Storage.get('userInfo')

// 移除数据
Storage.remove('userInfo')

// 清空所有数据
Storage.clear()

2. 高级存储方案

2.1 加密存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// utils/crypto.js
import CryptoJS from 'crypto-js'

const SECRET_KEY = 'your-secret-key'

export const encrypt = (data) => {
return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString()
}

export const decrypt = (ciphertext) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, SECRET_KEY)
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8))
}

// 加密存储类
class SecureStorage {
static set(key, value, expired = 0) {
const data = {
value: encrypt(value),
expired: expired ? Date.now() + expired * 1000 : 0
}
uni.setStorageSync(key, JSON.stringify(data))
}

static get(key) {
const data = uni.getStorageSync(key)
if (!data) return null

const { value, expired } = JSON.parse(data)
if (expired && expired < Date.now()) {
uni.removeStorageSync(key)
return null
}
return decrypt(value)
}
}

2.2 数据压缩存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// utils/compress.js
import { deflate, inflate } from 'pako'

class CompressStorage {
static set(key, value) {
// 转换为JSON字符串并压缩
const compressed = deflate(JSON.stringify(value))
uni.setStorageSync(key, compressed)
}

static get(key) {
const compressed = uni.getStorageSync(key)
if (!compressed) return null

// 解压并解析JSON
const decompressed = inflate(compressed, { to: 'string' })
return JSON.parse(decompressed)
}
}

3. 持久化存储策略

3.1 Vuex持久化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import Storage from '@/utils/storage'

Vue.use(Vuex)

const STORAGE_KEY = 'vuex_store'

export default new Vuex.Store({
state: {
userInfo: null,
settings: {}
},
mutations: {
setState(state, payload) {
Object.assign(state, payload)
}
},
actions: {
// 初始化状态
initState({ commit }) {
const data = Storage.get(STORAGE_KEY)
if (data) {
commit('setState', data)
}
},
// 保存状态
saveState({ state }) {
Storage.set(STORAGE_KEY, state)
}
}
})

3.2 自动同步机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// mixins/storage-sync.js
export default {
created() {
// 监听应用进入后台
uni.onAppHide(() => {
this.$store.dispatch('saveState')
})

// 监听网络状态
uni.onNetworkStatusChange(({ isConnected }) => {
if (isConnected) {
this.syncDataToServer()
}
})
},
methods: {
async syncDataToServer() {
try {
const localData = Storage.get('offlineData') || []
if (localData.length === 0) return

// 上传本地数据到服务器
await this.$api.syncData(localData)
// 清空本地缓存
Storage.remove('offlineData')
} catch (err) {
console.error('数据同步失败', err)
}
}
}
}

4. 存储优化技巧

4.1 分片存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class ChunkStorage {
static CHUNK_SIZE = 1024 * 1024 // 1MB

static set(key, value) {
const data = JSON.stringify(value)
const chunks = []

// 分片存储
for (let i = 0; i < data.length; i += this.CHUNK_SIZE) {
const chunk = data.slice(i, i + this.CHUNK_SIZE)
chunks.push(chunk)
}

// 存储分片信息
uni.setStorageSync(`${key}_info`, {
chunks: chunks.length,
timestamp: Date.now()
})

// 存储各个分片
chunks.forEach((chunk, index) => {
uni.setStorageSync(`${key}_${index}`, chunk)
})
}

static get(key) {
const info = uni.getStorageSync(`${key}_info`)
if (!info) return null

// 合并分片
let data = ''
for (let i = 0; i < info.chunks; i++) {
const chunk = uni.getStorageSync(`${key}_${i}`)
data += chunk
}

return JSON.parse(data)
}
}

4.2 存储监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class StorageMonitor {
static async checkSize() {
try {
const { currentSize, limitSize } = await uni.getStorageInfo()
const usage = (currentSize / limitSize) * 100

if (usage > 80) {
console.warn(`存储空间使用率过高: ${usage.toFixed(2)}%`)
this.cleanExpiredData()
}
} catch (err) {
console.error('存储监控失败', err)
}
}

static cleanExpiredData() {
const keys = uni.getStorageInfoSync().keys
keys.forEach(key => {
const data = uni.getStorageSync(key)
if (data && data.expired && data.expired < Date.now()) {
uni.removeStorageSync(key)
}
})
}
}

5. 实践建议

5.1 性能优化

  1. 避免频繁读写操作
  2. 合理使用过期时间
  3. 及时清理无用数据
  4. 大数据考虑分片存储

5.2 安全建议

  1. 敏感数据必须加密
  2. 定期清理过期数据
  3. 避免存储明文密码
  4. 控制存储大小

6. 总结

  1. 合理封装Storage API
  2. 选择合适的存储方案
  3. 实现数据持久化
  4. 注意性能和安全
  5. 做好存储监控

如果觉得文章对你有帮助,欢迎点赞、评论、分享,你的支持是我继续创作的动力!

上一篇 uni-app组件通信完全指南:从基础到进阶
下一篇 uni-app网络请求最佳实践:封装、拦截与错误处理
感谢您的支持!
微信赞赏码 微信赞赏
支付宝赞赏码 支付宝赞赏