跳到主要内容

useStorage

分类
导出大小
2 kB
上次更改
2 个月前
相关

创建一个响应式引用,用于访问和修改 LocalStorageSessionStorage

默认使用 localStorage,其他存储源可以通过第三个参数指定。

演示

name: Banana
color: Yellow
size: Medium
count: 0

用法

提示

在 Nuxt 3 中使用时,此函数将不会被自动导入,因为 Nitro 内置了 useStorage()。如果您想使用 VueUse 中的此函数,请显式导入。

ts
import { 
useStorage
} from '@vueuse/core'
// bind object const
state
=
useStorage
('my-store', {
hello
: 'hi',
greeting
: 'Hello' })
// bind boolean const
flag
=
useStorage
('my-flag', true) // returns Ref<boolean>
// bind number const
count
=
useStorage
('my-count', 0) // returns Ref<number>
// bind string with SessionStorage const
id
=
useStorage
('my-id', 'some-string-id',
sessionStorage
) // returns Ref<string>
// delete data from storage
state
.
value
= null

合并默认值

默认情况下,如果存储中存在值,useStorage 将使用存储中的值并忽略默认值。请注意,当您向默认值添加更多属性时,如果客户端存储中没有该键,则该键可能为 undefined

ts
localStorage
.
setItem
('my-store', '{"hello": "hello"}')
const
state
=
useStorage
('my-store', {
hello
: 'hi',
greeting
: 'hello' },
localStorage
)
console
.
log
(
state
.
value
.
greeting
) // undefined, since the value is not presented in storage

为了解决这个问题,您可以启用 mergeDefaults 选项。

ts
localStorage
.
setItem
('my-store', '{"hello": "nihao"}')
const
state
=
useStorage
(
'my-store', {
hello
: 'hi',
greeting
: 'hello' },
localStorage
,
{
mergeDefaults
: true } // <--
)
console
.
log
(
state
.
value
.
hello
) // 'nihao', from storage
console
.
log
(
state
.
value
.
greeting
) // 'hello', from merged default value
js
localStorage.setItem('my-store', '{"hello": "nihao"}')
const state = useStorage(
  'my-store',
  { hello: 'hi', greeting: 'hello' },
  localStorage,
  { mergeDefaults: true },
)
console.log(state.value.hello) // 'nihao', from storage
console.log(state.value.greeting) // 'hello', from merged default value

当将其设置为 true 时,它将对对象执行浅合并。您可以传入一个函数来执行自定义合并(例如深合并),例如:

ts
const 
state
=
useStorage
(
'my-store', {
hello
: 'hi',
greeting
: 'hello' },
localStorage
,
{
mergeDefaults
: (
storageValue
,
defaults
) => deepMerge(
defaults
,
storageValue
) } // <--
)
js
const state = useStorage(
  'my-store',
  { hello: 'hi', greeting: 'hello' },
  localStorage,
  {
    mergeDefaults: (storageValue, defaults) =>
      deepMerge(defaults, storageValue),
  },
)

自定义序列化

默认情况下,useStorage 将根据所提供默认值的数据类型智能地使用相应的序列化器。例如,对象将使用 JSON.stringify / JSON.parse,数字将使用 Number.toString / parseFloat 等。

您还可以为 useStorage 提供自己的序列化函数

ts
import { 
useStorage
} from '@vueuse/core'
useStorage
(
'key', {},
undefined
,
{
serializer
: {
read
: (
v
: any) =>
v
?
JSON
.
parse
(
v
) : null,
write
: (
v
: any) =>
JSON
.
stringify
(
v
),
}, }, )
js
import { useStorage } from '@vueuse/core'
useStorage('key', {}, undefined, {
  serializer: {
    read: (v) => (v ? JSON.parse(v) : null),
    write: (v) => JSON.stringify(v),
  },
})

请注意,当您提供 null 作为默认值时,useStorage 无法从中推断数据类型。在这种情况下,您可以提供自定义序列化器或显式重用内置序列化器。

ts
import { 
StorageSerializers
,
useStorage
} from '@vueuse/core'
const
objectLike
=
useStorage
('key', null,
undefined
, {
serializer
:
StorageSerializers
.
object
})
objectLike
.
value
= {
foo
: 'bar' }

类型声明

显示类型声明
ts
export interface 
Serializer
<
T
> {
read
: (
raw
: string) =>
T
write
: (
value
:
T
) => string
} export interface
SerializerAsync
<
T
> {
read
: (
raw
: string) =>
Awaitable
<
T
>
write
: (
value
:
T
) =>
Awaitable
<string>
} export declare const
StorageSerializers
:
Record
<
"boolean" | "object" | "number" | "any" | "string" | "map" | "set" | "date",
Serializer
<any>
> export declare const
customStorageEventName
= "vueuse-storage"
export interface StorageEventLike {
storageArea
:
StorageLike
| null
key
: StorageEvent["key"]
oldValue
: StorageEvent["oldValue"]
newValue
: StorageEvent["newValue"]
} export interface
UseStorageOptions
<
T
>
extends ConfigurableEventFilter, ConfigurableWindow, ConfigurableFlush { /** * Watch for deep changes * * @default true */
deep
?: boolean
/** * Listen to storage changes, useful for multiple tabs application * * @default true */
listenToStorageChanges
?: boolean
/** * Write the default value to the storage when it does not exist * * @default true */
writeDefaults
?: boolean
/** * Merge the default value with the value read from the storage. * * When setting it to true, it will perform a **shallow merge** for objects. * You can pass a function to perform custom merge (e.g. deep merge), for example: * * @default false */
mergeDefaults
?: boolean | ((
storageValue
:
T
,
defaults
:
T
) =>
T
)
/** * Custom data serialization */
serializer
?:
Serializer
<
T
>
/** * On error callback * * Default log error to `console.error` */
onError
?: (
error
: unknown) => void
/** * Use shallow ref as reference * * @default false */
shallow
?: boolean
/** * Wait for the component to be mounted before reading the storage. * * @default false */
initOnMounted
?: boolean
} export declare function
useStorage
(
key
:
MaybeRefOrGetter
<string>,
defaults
:
MaybeRefOrGetter
<string>,
storage
?:
StorageLike
,
options
?:
UseStorageOptions
<string>,
):
RemovableRef
<string>
export declare function
useStorage
(
key
:
MaybeRefOrGetter
<string>,
defaults
:
MaybeRefOrGetter
<boolean>,
storage
?:
StorageLike
,
options
?:
UseStorageOptions
<boolean>,
):
RemovableRef
<boolean>
export declare function
useStorage
(
key
:
MaybeRefOrGetter
<string>,
defaults
:
MaybeRefOrGetter
<number>,
storage
?:
StorageLike
,
options
?:
UseStorageOptions
<number>,
):
RemovableRef
<number>
export declare function
useStorage
<
T
>(
key
:
MaybeRefOrGetter
<string>,
defaults
:
MaybeRefOrGetter
<
T
>,
storage
?:
StorageLike
,
options
?:
UseStorageOptions
<
T
>,
):
RemovableRef
<
T
>
export declare function
useStorage
<
T
= unknown>(
key
:
MaybeRefOrGetter
<string>,
defaults
:
MaybeRefOrGetter
<null>,
storage
?:
StorageLike
,
options
?:
UseStorageOptions
<
T
>,
):
RemovableRef
<
T
>

来源

源码演示文档

贡献者

Anthony Fu
Fernando Fernández
Robin
Anthony Fu
James Garbutt
IlyaL
sun0day
Jelf
Jeffrey Li
SerKo
Yauheni Vasiukevich
OrbisK
Callum Macrae
Isaac Qadri
Matt Sanders
Doctorwu
Eduardo San Martin Morote
丶远方
Daniel Maixner
chenglu
David Ma
Daniel Mittereder
Clément Ollivier
Yury Rudey
Puru Vijay
webfansplz
spking11
Maurici Abad Gutierrez
吉约姆·肖
Denis Blazhkun
Andreas Weber
Le Minh Tri
Jamie Warburton
Shinigami
Sasan Farrokh
Pig Fang
wheat
Alex Kozack
Nurettin Kaya
Pine
Antério Vieira
Ivan Demchuk

更新日志

v13.7.0
22116 - 修复:确保当新值为 undefined 时始终读取数据(#4957
v13.2.0
65a99 - 修复:在 useStorage 中始终挂载监听器(#4730
v12.8.0
7432f - feat(types): 废弃 MaybeRefMaybeRefOrGetter,转而使用 Vue 的原生类型 (#4636)
v12.4.0
eb679 - 功能:使存储键具有响应性(#4464
dd316 - feat: 尽可能在所有地方使用被动事件处理程序 (#4477)
v12.3.0
59f75 - feat(toValue): 废弃 @vueuse/shared 中的 toValue,转而使用 Vue 的原生函数
0a9ed - feat!: 放弃对 Vue 2 的支持,优化打包并清理 (#4349)
v11.0.1
a9b49 - 修复:确保在同一文档中同步(#4152
5a302 - 功能:根据所使用的存储后端有条件地使用事件(#3822
v10.8.0
f7ea1 - 修复:确保将值设置为 null 可以同步到其他实例(#3737
a086e - fix: 更严格的类型
v10.7.0
04220 - 修复:修复未定义默认值的问题(#3597
v10.6.0
dc6f2 - 功能:为 SSR 添加 waitOnMounted 选项(#3504
b6d2b - 修复:修复默认值未解包的问题(#3534
v10.4.0
6fabe - 修复:仅在对象序列化方式不同时读取对象(#2782) (#3091)

根据 MIT 许可证发布。