본문 바로가기

Vue.js

[Vue.js] BroadcastChannel

이슈는

한 사용자가 같은 컴퓨터에서 탭을 여러 개 띄워놓고 같은 계정 or 다른 계정 을 같이 로그인 할 수 있어 

ATab에서 데이터를 변경하거나 어떤 처리를 했을 경우 다른 탭에 적용이 안되는 문제가 있었다. 

-> 필요한 해결 니즈

프로젝트에서 A탭에서 로그아웃 하고 다른 계정으로 로그인 했을 때 B탭에도 이를 동기화 하는 방법

 

 

ATab, BTab 이 있는 상황에서 ATab이 로그아웃 할 경우 브라우저 내의 토큰 제거하는 로직으로 되어있었다.

하지만 이렇게 할 경우 BTab 에선 ATab 에서 일어난 로그아웃 이벤트가 전달되지 않았다 (cookie 나 storage에 토큰 제거 되어있는 상태)

그래서 로그인 되어 있는거 같은 화면에서 새로고침을 해야하는 상황인데

vueuse 의 BroadcastChannel API 를 사용해서 해결했다. (원래는 web 안에 iframe 과의 통신을 할 때 사용했던 것으로 알고 있었음.)

해당 채널을 만들고 post 함수와 함께 특정 값을 넣어 실행 시켜주면 다른 탭에서도 적용된걸 확인할 수 있다.

 

 

https://vueuse.org/core/useBroadcastChannel/#usebroadcastchannel

 

VueUse

Collection of essential Vue Composition Utilities

vueuse.org

https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel

 

BroadcastChannel - Web APIs | MDN

The BroadcastChannel interface represents a named channel that any browsing context of a given origin can subscribe to. It allows communication between different documents (in different windows, tabs, frames or iframes) of the same origin. Messages are bro

developer.mozilla.org

 

 

// 로그아웃에 적용


<template>
    <q-list>
      <q-item clickable v-close-popup>
        <q-item-section @click="handleClickLogout">
          <q-item-label>로그아웃</q-item-label>
        </q-item-section>
      </q-item>
    </q-list>

</template>

<script lang="ts">
import { computed, defineComponent, watchEffect } from 'vue'
import { useBroadcastChannel } from '@vueuse/core'
import { useAuthStore } from '@/stores'

...

export default defineComponent({
  setup() {
    const authStore = useAuthStore()
    const router = useRouter()

    const { data, post } = useBroadcastChannel({ name: 'Taffice' })

    watchEffect(async () => {
      if (data.value === 'logout') {
        await authStore.logout()
        await router.push('/login')
      }
    })

    return {
      handleClickLogout: async () => {
        post('logout')
        await authStore.logout()
        await router.push('/login')
      },
    }
  },
})


</script>

 

 

 

 

728x90
반응형

'Vue.js' 카테고리의 다른 글

v-model  (0) 2023.09.03
[Vue.js] Options API vs Composition API  (0) 2023.02.12
[Vue.js] 컴포넌트에 대해  (0) 2023.02.09
[Vue.js] 뷰 컴포넌트  (0) 2022.05.01
[Vue.js] Vue Instance  (0) 2022.05.01