Skip to content

本地缓存 - storage

与 storage 相关的一些方法和 hooks,强烈建议在项目中使用它们。

storage

为了提高 localStorage 的功能性和灵活性,我们对其进行了封装,以支持设置过期时间。这个封装版本允许开发者定义数据存储的有效期,进一步优化了数据管理和应用性能。具体使用方法可以参考文档

useStorage

为了在模板中方便使用缓存值,通常我们会用一个变量保存这些值,并确保其能够在修改 storage 数据时同步更新。手动实现这一过程较为繁琐,因此我们推荐使用这个 Hooks 进行管理,它可以轻松实现变量与 storage 数据的自动同步,简化开发流程。

js
const STORAGE_KET = {
  ENABLE: 'enable',
}

const enableStorage = useStorage(STORAGE_KET.ENABLE, false)

console.log(enableStorage.value) // false

enableStorage.set(true, {
  // 需要注意,当数据过期后,仅会在下次进入页面时将数据恢复默认值
  // 如果一直停留在当前页面,则数据不会恢复默认值
  expiredAt: dayjs().add(1, 'day').unix(),
})

// 注意,它不是一个 ref 变量,不能省略 .value
<view>{{ enableStorage.value }}</view>

如果希望该变量是跨页面同步的,可以将其放入 pinia 中管理:

js
import {defineStore} from 'pinia'
import {ref} from 'vue'
import {useStorage} from '@ifanrx/uni-mp'

const STORAGE_KET = {
  ENABLE: 'enable',
}

export default defineStore('shared-storage', () => {
  const enableStorage = useStorage(STORAGE_KET.ENABLE, false)

  const enable = computed(() => enableStorage.value)

  const setEnable = value => {
    enableStorage.set(value)
  }

  return {
    enable,
    setEnable,
  }
})
vue
<script setup>
import {router, storage} from '@ifanrx/uni-mp'
import {storeToRefs} from 'pinia'

import useSharedStorage from './use-shared-storage'

const sharedStorage = useSharedStorage()

const {enable} = storeToRefs(sharedStorage)
const {setEnable} = sharedStorage

useStorageMap

useStorageMap 适用于保存一系列相似的数据,将其统一管理,例如:弹窗是否显示、未读消息等。

TIP

请正确区分 useStorageuseStorageMapuseStorage 适合用于管理单一的数据。而 useStorageMap 更使用管理一系列类似的数据,支持单独设置每条数据的过期时间;举例来说,假设一个应用中有很多区域,每切换到一个新的区域时都要弹窗,后面不会再弹,对于这种场景,使用 useStorageMap 会简单很多,我们可以将这类信息存放在一个名为 viewed_area_welcome_modalmap 中,然后通过区域名称作为 key 去记录每个区域的状态。而如果使用 useStorage 则较为麻烦,我们要么将每个区域的状态使用区域名称作为 storage 的 key 单独存放,要么统一存放并用 map 处理,而 useStorageMap 就是帮助我们方便地操作这个 map

读取和更新

对于上面的例子,我们只需要这么做:

js
import {useStorageMap} from '@ifanrx/uni-mp'

const area = '广东'
const welcomeStorageMap = useStorageMap('viewed_area_welcome_modal')

// 当 set 的时候,这个 computed 会触发更新
const showWelcome = computed(() => !welcomeStorageMap.get(area))

const onCloseMessage = () => {
  welcomeStorageMap.set(area)
}

如此一来,当我们调用 viewedAreaWelcomeModal.set 的时候,showWelcome 就会自动更新。

如果情况再复杂点,需要精确到省市区,可以改成这样:

js
import {useStorageMap} from '@ifanrx/uni-mp'

// useStorageMap 内部会将数组合并成字符串作为每条记录的 key
const area = ['广东', '广州', '海珠'] 
const welcomeStorageMap = useStorageMap('viewed_area_welcome_modal')

const showWelcome = computed(() => !welcomeStorageMap.get(area))

const onCloseMessage = () => {
  welcomeStorageMap.set(area)
}

传入 value

如果需要记录更多状态,可以在 set 方法传入 value

js
const onCloseMessage = () => {
  welcomeStorageMap.set(area, {
    value: {
      viewed: true,
      ...其它信息,
    },
  })
}

过期时间

如果需要设定时间范围,比如一天之内只显示一次,我们也可以指定过期时间:

js
const onCloseMessage = () => {
  welcomeStorageMap.set(area, {
    value: {
      viewed: true,
      ...其它信息
    },
    // 绝对时间戳
    expiredAt: dayjs().add(1, 'day').unix(),

    // 或者用相对时间(秒)
    expiresIn: 60 * 10
  })
}

如果当前记录已过期,get 方法将自动清除数据并返回空。

WARNING

注意:当 expiredAt 和 expiresIn 同时设置,expiredAt 优先级更高。

相关文档