Skip to content

⬅️ Back to Table of Contents

📄 useStorage

📊 Analysis Summary

Metric Count
🔧 Functions 24
📦 Imports 19
📊 Variables & Constants 2
🟢 Vue Composition API 2
📐 Interfaces 4

📚 Table of Contents

🛠️ File Location:

📂 packages/core/useStorage/index.ts

📦 Imports

Name Source
Awaitable @vueuse/shared
ConfigurableEventFilter @vueuse/shared
ConfigurableFlush @vueuse/shared
RemovableRef @vueuse/shared
MaybeRefOrGetter vue
ConfigurableWindow ../_configurable
StorageLike ../ssr-handlers
tryOnMounted @vueuse/shared
watchPausable @vueuse/shared
computed vue
deepRef vue
nextTick vue
shallowRef vue
toValue vue
watch vue
defaultWindow ../_configurable
getSSRHandler ../ssr-handlers
useEventListener ../useEventListener
guessSerializerType ./guess

Variables & Constants

Name Type Kind Value Exported
StorageSerializers Record<'boolean' \| 'object' \| 'numb... const { boolean: { read: (v: any) => v === 'true', write: (v: any) => String(v), },...
customStorageEventName "vueuse-storage" const 'vueuse-storage'

Vue Composition API

Name Type Reactive Variables Composables
computed computed none none
watch watch none none

Functions

boolean.read(v: any): boolean

Parameters:

  • v any

Returns: boolean

Code
(v: any) => v === 'true'

boolean.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • String
Code
(v: any) => String(v)

object.read(v: any): any

Parameters:

  • v any

Returns: any

Calls:

  • JSON.parse
Code
(v: any) => JSON.parse(v)

object.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • JSON.stringify
Code
(v: any) => JSON.stringify(v)

number.read(v: any): number

Parameters:

  • v any

Returns: number

Calls:

  • Number.parseFloat
Code
(v: any) => Number.parseFloat(v)

number.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • String
Code
(v: any) => String(v)

any.read(v: any): any

Parameters:

  • v any

Returns: any

Code
(v: any) => v

any.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • String
Code
(v: any) => String(v)

string.read(v: any): any

Parameters:

  • v any

Returns: any

Code
(v: any) => v

string.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • String
Code
(v: any) => String(v)

map.read(v: any): Map<unknown, unknown>

Parameters:

  • v any

Returns: Map<unknown, unknown>

Code
(v: any) => new Map(JSON.parse(v))

map.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • JSON.stringify
Code
(v: any) => JSON.stringify(Array.from((v as Map<any, any>).entries()))

set.read(v: any): Set<unknown>

Parameters:

  • v any

Returns: Set<unknown>

Code
(v: any) => new Set(JSON.parse(v))

set.write(v: any): string

Parameters:

  • v any

Returns: string

Calls:

  • JSON.stringify
Code
(v: any) => JSON.stringify(Array.from(v as Set<any>))

date.read(v: any): Date

Parameters:

  • v any

Returns: Date

Code
(v: any) => new Date(v)

date.write(v: any): any

Parameters:

  • v any

Returns: any

Calls:

  • v.toISOString
Code
(v: any) => v.toISOString()

useStorage(key: MaybeRefOrGetter<string>, defaults: MaybeRefOrGetter<string>, storage: StorageLike, options: UseStorageOptions<string>): RemovableRef<string>

Parameters:

  • key MaybeRefOrGetter<string>
  • defaults MaybeRefOrGetter<string>
  • storage StorageLike
  • options UseStorageOptions<string>

Returns: RemovableRef<string>

Code
export function useStorage(key: MaybeRefOrGetter<string>, defaults: MaybeRefOrGetter<string>, storage?: StorageLike, options?: UseStorageOptions<string>): RemovableRef<string>

Internal helpers

Declared inside another function in this file.

onStorageEvent(ev: StorageEvent): void

Parameters:

  • ev StorageEvent

Returns: void

Calls:

  • update
Code
(ev: StorageEvent): void => {
    if (initOnMounted && !firstMounted) {
      return
    }

    update(ev)
  }

onStorageCustomEvent(ev: CustomEvent<StorageEventLike>): void

Parameters:

  • ev CustomEvent<StorageEventLike>

Returns: void

Calls:

  • updateFromCustomEvent
Code
(ev: CustomEvent<StorageEventLike>): void => {
    if (initOnMounted && !firstMounted) {
      return
    }

    updateFromCustomEvent(ev)
  }

dispatchWriteEvent(oldValue: string | null, newValue: string | null): void

Parameters:

  • oldValue string | null
  • newValue string | null

Returns: void

Calls:

  • window.dispatchEvent

Internal Comments:

// send custom event to communicate within same page
// We also use a CustomEvent since StorageEvent cannot (x4)
// be constructed with a non-built-in storage area (x4)

Code
function dispatchWriteEvent(oldValue: string | null, newValue: string | null) {
    // send custom event to communicate within same page
    if (window) {
      const payload = {
        key: keyComputed.value,
        oldValue,
        newValue,
        storageArea: storage as Storage,
      }
      // We also use a CustomEvent since StorageEvent cannot
      // be constructed with a non-built-in storage area
      window.dispatchEvent(storage instanceof Storage
        ? new StorageEvent('storage', payload)
        : new CustomEvent<StorageEventLike>(customStorageEventName, {
            detail: payload,
          }))
    }
  }

useStorage.write(v: unknown): void

Parameters:

  • v unknown

Returns: void

Calls:

  • storage!.getItem
  • dispatchWriteEvent
  • storage!.removeItem
  • serializer.write
  • storage!.setItem
  • onError
Code
function write(v: unknown) {
    try {
      const oldValue = storage!.getItem(keyComputed.value)

      if (v == null) {
        dispatchWriteEvent(oldValue, null)
        storage!.removeItem(keyComputed.value)
      }
      else {
        const serialized = serializer.write(v as any)
        if (oldValue !== serialized) {
          storage!.setItem(keyComputed.value, serialized)
          dispatchWriteEvent(oldValue, serialized)
        }
      }
    }
    catch (e) {
      onError(e)
    }
  }

useStorage.read(event: StorageEventLike): any

Parameters:

  • event StorageEventLike

Returns: any

Calls:

  • storage!.getItem
  • storage!.setItem
  • serializer.write
  • serializer.read
  • mergeDefaults
  • Array.isArray
Code
function read(event?: StorageEventLike) {
    const rawValue = event
      ? event.newValue
      : storage!.getItem(keyComputed.value)

    if (rawValue == null) {
      if (writeDefaults && rawInit != null)
        storage!.setItem(keyComputed.value, serializer.write(rawInit))
      return rawInit
    }
    else if (!event && mergeDefaults) {
      const value = serializer.read(rawValue)
      if (typeof mergeDefaults === 'function')
        return mergeDefaults(value, rawInit)
      else if (type === 'object' && !Array.isArray(value))
        return { ...rawInit as any, ...value }
      return value
    }
    else if (typeof rawValue !== 'string') {
      return rawValue
    }
    else {
      return serializer.read(rawValue)
    }
  }

update(event: StorageEventLike): void

Parameters:

  • event StorageEventLike

Returns: void

Calls:

  • pauseWatch
  • serializer.write
  • read
  • onError
  • nextTick (from vue)
  • resumeWatch

Internal Comments:

// use nextTick to avoid infinite loop

Code
function update(event?: StorageEventLike) {
    if (event && event.storageArea !== storage)
      return

    if (event && event.key == null) {
      data.value = rawInit
      return
    }

    if (event && event.key !== keyComputed.value) {
      return
    }

    pauseWatch()

    try {
      const serializedData = serializer.write(data.value)
      if (event === undefined || event?.newValue !== serializedData) {
        data.value = read(event)
      }
    }
    catch (e) {
      onError(e)
    }
    finally {
      // use nextTick to avoid infinite loop
      if (event)
        nextTick(resumeWatch)
      else
        resumeWatch()
    }
  }

updateFromCustomEvent(event: CustomEvent<StorageEventLike>): void

Parameters:

  • event CustomEvent<StorageEventLike>

Returns: void

Calls:

  • update
Code
function updateFromCustomEvent(event: CustomEvent<StorageEventLike>) {
    update(event.detail)
  }

Interfaces

Serializer<T>

Interface Code
export interface Serializer<T> {
  read: (raw: string) => T
  write: (value: T) => string
}

Properties

Name Type Optional Description
read (raw: string) => T not shown
write (value: T) => string not shown

SerializerAsync<T>

Interface Code
export interface SerializerAsync<T> {
  read: (raw: string) => Awaitable<T>
  write: (value: T) => Awaitable<string>
}

Properties

Name Type Optional Description
read (raw: string) => Awaitable<T> not shown
write (value: T) => Awaitable<string> not shown

StorageEventLike

Interface Code
export interface StorageEventLike {
  storageArea: StorageLike | null
  key: StorageEvent['key']
  oldValue: StorageEvent['oldValue']
  newValue: StorageEvent['newValue']
}

Properties

Name Type Optional Description
storageArea StorageLike \| null not shown
key StorageEvent['key'] not shown
oldValue StorageEvent['oldValue'] not shown
newValue StorageEvent['newValue'] not shown

UseStorageOptions<T>

Interface Code
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
}

Properties

Name Type Optional Description
deep boolean not shown
listenToStorageChanges boolean not shown
writeDefaults boolean not shown
mergeDefaults boolean \| ((storageValue: T, defaults: T) => T) not shown
serializer Serializer<T> not shown
onError (error: unknown) => void not shown
shallow boolean not shown
initOnMounted boolean not shown

Generated by Syntax Scribe