76 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			76 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 전역 로딩 상태 관리 스토어 (로딩 카운터 방식)
							 | 
						||
| 
								 | 
							
								 * 여러 비동기 작업이 동시에 진행되어도 안전하게 로딩 상태를 관리합니다.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export const useLoadingStore = defineStore(
							 | 
						||
| 
								 | 
							
								  "loading",
							 | 
						||
| 
								 | 
							
								  () => {
							 | 
						||
| 
								 | 
							
								    // 로딩 카운터 - 0보다 크면 로딩 중
							 | 
						||
| 
								 | 
							
								    const loadingCount = ref(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 현재 로딩 중인 작업들의 메시지
							 | 
						||
| 
								 | 
							
								    const loadingMessages = ref<string[]>([]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 로딩 상태 (카운터가 0보다 크면 true)
							 | 
						||
| 
								 | 
							
								    const isLoading = computed(() => loadingCount.value > 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 현재 로딩 메시지 (가장 최근 메시지 또는 기본 메시지)
							 | 
						||
| 
								 | 
							
								    const currentMessage = computed(
							 | 
						||
| 
								 | 
							
								      () =>
							 | 
						||
| 
								 | 
							
								        loadingMessages.value[loadingMessages.value.length - 1] || "로딩 중..."
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 로딩 시작
							 | 
						||
| 
								 | 
							
								    const startLoading = (message?: string) => {
							 | 
						||
| 
								 | 
							
								      loadingCount.value++;
							 | 
						||
| 
								 | 
							
								      if (message) {
							 | 
						||
| 
								 | 
							
								        loadingMessages.value.push(message);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 로딩 종료
							 | 
						||
| 
								 | 
							
								    const stopLoading = (message?: string) => {
							 | 
						||
| 
								 | 
							
								      loadingCount.value = Math.max(0, loadingCount.value - 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (message && loadingMessages.value.length > 0) {
							 | 
						||
| 
								 | 
							
								        const index = loadingMessages.value.lastIndexOf(message);
							 | 
						||
| 
								 | 
							
								        if (index > -1) {
							 | 
						||
| 
								 | 
							
								          loadingMessages.value.splice(index, 1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else if (loadingMessages.value.length > 0) {
							 | 
						||
| 
								 | 
							
								        // 메시지가 지정되지 않으면 가장 최근 메시지 제거
							 | 
						||
| 
								 | 
							
								        loadingMessages.value.pop();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 모든 로딩 강제 종료
							 | 
						||
| 
								 | 
							
								    const clearAllLoading = () => {
							 | 
						||
| 
								 | 
							
								      loadingCount.value = 0;
							 | 
						||
| 
								 | 
							
								      loadingMessages.value = [];
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // 로딩 상태 리셋
							 | 
						||
| 
								 | 
							
								    const reset = () => {
							 | 
						||
| 
								 | 
							
								      loadingCount.value = 0;
							 | 
						||
| 
								 | 
							
								      loadingMessages.value = [];
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      // 상태
							 | 
						||
| 
								 | 
							
								      loadingCount: readonly(loadingCount),
							 | 
						||
| 
								 | 
							
								      loadingMessages: readonly(loadingMessages),
							 | 
						||
| 
								 | 
							
								      isLoading,
							 | 
						||
| 
								 | 
							
								      currentMessage,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // 액션
							 | 
						||
| 
								 | 
							
								      startLoading,
							 | 
						||
| 
								 | 
							
								      stopLoading,
							 | 
						||
| 
								 | 
							
								      clearAllLoading,
							 | 
						||
| 
								 | 
							
								      reset,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    persist: false, // 로딩 상태는 새로고침 시 초기화되어야 함
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								);
							 |