ABOUT ME

-

  • [ Vue ] Spinner Delay 적용해서 사용하기
    Front/Vue 2025. 9. 2. 22:13
    반응형

    로딩하는 과정을 표현하기 위해서 spinner를 이용

    spinner component는 이렇게 만들어서 사용

    <script setup lang="ts">
    
    </script>
    
    <template>
    <div class="app-spinner-wrapper">
      <div class="spinner"/>
    </div>
    </template>
    
    <style scoped lang="scss">
    .app-spinner-wrapper {
      width: fit-content;
      height: fit-content;
    
      .spinner {
        width: 15px;
        height: 15px;
        border: 3px solid #e8e8e8;
        border-top-color: var(--app-theme-text-color);
        border-radius: 50%;
        animation: spin 0.8s linear infinite;
      }
    
      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }
    }
    </style>

    그럼 이런 식의 모양의 spinner 가 나오며 border는 스피너의 크기이며, border-top-color는 spinner의 로딩바 색상을 나타낸다.

    그럼 spinner는 기본적으로 로딩 시작 전후로 나뉘어서 나타났다가 사라져야하므로

     

    이 기능을 구현 하기 위해 true false변수를 사용

    store를 사용하여 spinner의 렌더링 여부를 결정

    const loadingSpinner = ref(false);
    <app-spinner v-if="appStore.loadingSpinner"/>

     

    사용시에는 이 loadingSpinner의 값만 타이밍에 맞춰서 바꿔주기만 하면 된다.

    하지만 단순히 이렇게 설정한 경우에는 바로 요청시 spinner가 돌면 결과가 엄청 빨리 return되는 경우에도 spinner가 나오게 된다.

     

    이를 막기 위해서 spinner생성 조건에서도 약간의 지연을 주어 n초 후 가 지나도 결과가 return이 안되면 spinner가 나오도록 구현

    let loadingTimeout: ReturnType<typeof setTimeout> | null = null;
        const loadingSpinner = ref(false);
    
        const awaitLoading = (loading: boolean) => {
            if (loading) {
                if (loadingTimeout) {
                    clearTimeout(loadingTimeout);
                }
    
                loadingTimeout = setTimeout(() => {
                    loadingSpinner.value = true;
                }, 2000);
            } else {
                if (loadingTimeout) {
                    clearTimeout(loadingTimeout);
                    loadingTimeout = null;
                }
    
                loadingSpinner.value = false;
            }
        };

     

    실제 awaitLoading 함수를 만들어서 true 값이 들어왔을때에는 2초동안 false값이 안들어오면 spinner가 나오게 했고,

    2초전에 끝나면 spinner가 사라지도록 했다.

    const cleanDB = async () => {
      const beforeTimestamp = Date.now() - 180 * MS_PER_DAY;
    
      appStore.awaitLoading(true)
    
      await cleanUpOldMemo(beforeTimestamp)
      await cleanUpOldTodo(beforeTimestamp)
    
      if(padStore.currentMemoPadId) {
        await memoStore.get(padStore.currentMemoPadId)
      }
      await todoStore.initalized()
      await refreshIndexDBStorage()
    
      appStore.awaitLoading(false)
    }

     

    실제 사용은 메모리 정리 기능을 구현하면서 spinner가 필요할 것 같아서 적용

    사용은 awaitLoading(true) 와 false사이에 로딩이 필요한 기능을 넣고 사용하면 된다.

    728x90
    반응형