🧠

Nuxt3のuseStateの値をlocalStorageを使って永続化する

2023/09/08に公開

以下を参考にしてNuxt3バージョンを作ったメモです。
ページを更新したりブラウザを開き直しても保持される変数を作ります。

https://zenn.dev/ignorant_kenji/articles/7348a0811c479f

以下のように useState のラッパークラスを1つ用意します。

composables/persist.ts
export const usePersistState = <T>(key: string, init: () => T): Ref<T> => {
  const initResult: T = init()
  let storedValue = null
  try {
    storedValue = JSON.parse(localStorage.getItem(key) + '') // nullはkey無し・空文字列はkey有り
  } catch { }
  // nullなら新規追加
  if (storedValue === null) localStorage.setItem(key, JSON.stringify(initResult))
  // 現在のstateに追加
  const refs: Ref<T> = useState<T>(key, () => ((storedValue !== null) ? storedValue : initResult) as T)
  // 変更検知
  watch(refs, newValue => localStorage.setItem(key, JSON.stringify(newValue)))
  return refs
}

export const removePersistState = (key: string): boolean => {
  const exist = localStorage.getItem(key)
  localStorage.removeItem(key)
  return (exist !== null)
}

これをcomponentsの中で使います。

components/menu.vue
<script setup lang="ts">
const debugMode = usePersistState<boolean>('debug_mode', () => true)
</script>

<template>
  <div>
    <h3>デバッグ表示</h3>
    <input id="debugSwitch" type="checkbox" v-model="debugMode.value">
  </div>
</template>

これは以下のような設定値を切り替えるトグルスイッチの例ですが、ページを更新したりタブやブラウザを閉じて開き直しても値が保持されるようになります。文字列や数値でも同様に使えます。

Image from Gyazo

補足

  • SSRのことは考慮できてないので、両方でレンダリングが発生するような場合はブラウザ側でのみlocalStorageが動くように作り替える必要があります。

https://crieit.net/posts/Nuxt-js-SSR

  • Nuxt3のuseStateについて基本的なことはこちら。

https://developer.mamezou-tech.com/nuxt/nuxt3-state-management/

Discussion