LoginSignup
1
3

More than 1 year has passed since last update.

VueでlocalStorageを監視して特定のキーの結果に応じて動作できる様にする

Last updated at Posted at 2022-10-24

はじめに

前回、vuex-persistedstateを利用して画面リロードでもログイン状態を保持できる様になったおかげで、ログイン状態の場合には画面を表示し、未ログイン状態の場合にはログイン画面へリダイレクト処理させることができました。

しかしここで新たな課題が発生します。

なんと別タブで画面表示した場合に、一方のタブでログアウトされたらもう一方のタブでもログイン画面へリダイレクトさせたいと言うのです。
調べてもなかなか別タブで変更されたstateやlocalStorageの値をwatchする方法が見つかりません。

さて、どうしよう…

StorageEventを使用する

Web Storage APIには、Storageオブジェクトが変更されるたびに発生するStorageEventが存在します。

このStorageEventを検知するためにイベントリスナを定義するサンプルコードがありました。

event.js
window.addEventListener('storage', function(e) {
  document.querySelector('.my-key').textContent = e.key;
  document.querySelector('.my-old').textContent = e.oldValue;
  document.querySelector('.my-new').textContent = e.newValue;
  document.querySelector('.my-url').textContent = e.url;
  document.querySelector('.my-storage').textContent = JSON.stringify(e.storageArea);
});

なるほど。addEventListenerを利用するのですね。
ということで、localStorageに保存したキー「auth_info」の有無によってログイン状態を判別するhookを用意しました。

hooks/login/useLoggedIn.ts
import { ref, useStore } from '@nuxtjs/composition-api'

export const useLoggedIn = () => {
  const store = useStore()
  const isLoggedIn = ref<boolean>(store.getters['auth/isLoggedIn'])

  // ローカルストレージのログイン状態を監視
  window.addEventListener('storage', (event) => {
    if (event.key === 'auth_info') {
      if (event.newValue) {
        isLoggedIn.value = true
      } else {
        isLoggedIn.value = false
      }
    }
  })

  return { isLoggedIn }
}

そしてlocalStorage.removeItem('auth_info')でキー自体を削除するコードをログアウト時の処理に組み込みました。
すると、上記のhookをページ内でwatchすることで、falseが返ってきた場合には未ログイン状態としてログイン画面へリダイレクトすることができました。

pages/main.vue
import { useLoggedIn } from '~/hooks/login/useLoggedIn'

export default defineComponent({
  components: {},
  layout: 'global',
  middleware: ['guard/auth'],
  setup() {
    const router = useRouter()

    const { isLoggedIn } = useLoggedIn()

    watch(isLoggedIn, (val) => {
      if (!val) {
        // ログアウトした場合はログイン画面へ遷移
        router.push('/login')
      }
    })

    return {}
  },
})

おわりに

薄々面倒だろうと気づいてはいましたが、やはり別タブの扱いは面倒でした。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3