uniapp+vue3 setup+ts 开发小程序实战(本地存储封装)-灵析社区

前端码农


为何要封装本地存储API

1、增加typescript数据类型提示:假设我们要获取本地数据,写法如下:

  const data = uni.getStorageSync(key)

这时我们输入key及访问data时,是获取不到类型提示的。

2、增加响应式:假设我们获取到上面的data之后,对data做了一些修改,这时我们又需要手动再次调用更新到本地

data = newValue
uni.setStorageSync(key, data)

目标希望封装之后的方法,在修改data后,自动调用存储api更新到本地(借助vue watch钩子)。

封装

根据上面的目标,先直接看封装后的代码:

import { ref, Ref, watch } from 'vue'
interface Company {
  companyName: string
  companyId: number
}

type StorageKeys = 'company' | 'companyList'

type ObjectType<T> = T extends 'company'
  ? Company
  : T extends 'companyList'
  ? Company[]
  : never

export function setStorage<T extends StorageKeys>(
  key: T,
  data: ObjectType<T>,
): void {
  uni.setStorageSync(key, data)
}

export function getStorage<T extends StorageKeys>(
  key: T,
  initValue: any = '',
): ObjectType<T> {
  const data = uni.getStorageSync(key) || initValue
  return data as ObjectType<T>
}

export function getStorageRef<T extends StorageKeys>(
  key: T,
  initValue: any = '',
): Ref<ObjectType<T>> {
  const data = uni.getStorageSync(key) || initValue
  const result = ref(data)
  watch(result.value, () => {
    setStorage(key, result.value)
  })
  return result as Ref<ObjectType<T>>
}

company | companyList: 示例数据,当前公司及公司列表

StorageKeys:定义所有本地存储数据keys

ObjectType :定义key对应的数据结构

setStorage:存储方法

getStorage:根据key获取数据方法(非响应式),适合于非直接渲染到template的场景,例如在函数中进行运算

getStorageRef:根据key获取数据方法(响应式),适合于直接渲染到template的场景,同时在修改数据时,无需手动调用存储api更新到本地

使用

<script setup lang="ts">
import { setStorage, getStorageRef } from "@/utils/storage"
const companyList = getStorageRef("companyList", [])
</script>

使用案例:搜索历史

使用本地存储最常见的案例就是存储搜索历史,下面代码就是当用户点击搜索结果后的代码逻辑

function next(item: Company) {
  const companyList = getStorageRef("companyList", [])
  const idx = companyList.value.findIndex(i => i.companyId === item.companyId)
  if (idx < 0) {
    companyList.value.unshift(item)
  } else {
    // 先删掉已有的,然后追加到前面(注意:这里不用手动调用存储方法更新到本地啦)
    companyList.value.splice(idx, 1)
    companyList.value.unshift(item)
  }
}

总结

以上封装只是用到了setStorageSync及setStorageSync两个方法,这两个已经能够满足我们绝大部分使用场景,如果你对本地存储api还有其他需求,如使用异步,开启加密存储(使用setStorage方法),可以自行添加封装方法即可。

阅读量:2013

点赞量:0

收藏量:0