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