Skip to content

useStorage

创建可用于访问和修改 LocalStorageSessionStorage 的反应式引用。

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

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

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

示例

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

用法

¥Usage

提示

当与 Nuxt 3 一起使用时,该函数不会自动导入,而是使用 Nitro 的内置 useStorage()。如果你想使用 VueUse 中的函数,请使用显式导入。

¥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.

js
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

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

¥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

要解决这个问题,你可以启用 mergeDefaults 选项。

¥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

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

¥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

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

¥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.

你还可以向 useStorage 提供自己的序列化函数:

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

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

¥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' }

类型声明

显示类型声明
typescript
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: string,
  defaults: MaybeRefOrGetter<string>,
  storage?: StorageLike,
  options?: UseStorageOptions<string>,
): RemovableRef<string>
export declare function useStorage(
  key: string,
  defaults: MaybeRefOrGetter<boolean>,
  storage?: StorageLike,
  options?: UseStorageOptions<boolean>,
): RemovableRef<boolean>
export declare function useStorage(
  key: string,
  defaults: MaybeRefOrGetter<number>,
  storage?: StorageLike,
  options?: UseStorageOptions<number>,
): RemovableRef<number>
export declare function useStorage<T>(
  key: string,
  defaults: MaybeRefOrGetter<T>,
  storage?: StorageLike,
  options?: UseStorageOptions<T>,
): RemovableRef<T>
export declare function useStorage<T = unknown>(
  key: string,
  defaults: MaybeRefOrGetter<null>,
  storage?: StorageLike,
  options?: UseStorageOptions<T>,
): RemovableRef<T>

源代码

源代码示例文档

变更日志

No recent changes

VueUse 中文网 - 粤ICP备13048890号