Skip to content

useStorage

Category
Export Size
2 kB
Last Changed
4 days ago
Related

Create a reactive ref that can be used to access & modify LocalStorage or SessionStorage.

Uses localStorage by default, other storage sources be specified via third argument.

Demo

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

Usage

TIP

When using with Nuxt 3, this function will NOT be auto imported in favor of Nitro's built-in useStorage(). Use explicit import if you want to use the function from 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

Merge Defaults

By default, useStorage will use the value from storage if it is present and ignores the default value. Be aware that when you are adding more properties to the default value, the key might be undefined if client's storage does not have that key.

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

To solve that, you can enable mergeDefaults option.

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

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:

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),
  },
)

Custom Serialization

By default, useStorage will smartly use the corresponding serializer based on the data type of provided default value. For example, JSON.stringify / JSON.parse will be used for objects, Number.toString / parseFloat for numbers, etc.

You can also provide your own serialization function to 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),
  },
})

Please note when you provide null as the default value, useStorage can't assume the data type from it. In this case, you can provide a custom serializer or reuse the built-in ones explicitly.

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

Type Declarations

Show Type Declarations
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
>

Source

SourceDemoDocs

Contributors

NoiseFan

Changelog

No recent changes

Released under the MIT License.