로딩
This commit is contained in:
parent
39dd213949
commit
dd855634a0
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<component :is="layout">
|
||||
<template #content>
|
||||
<LoadingSpinner :isLoading="loadingStore.isLoading" />
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
</component>
|
||||
@ -12,7 +13,10 @@ import { useRoute } from 'vue-router';
|
||||
import NormalLayout from './layouts/NormalLayout.vue';
|
||||
import NoLayout from './layouts/NoLayout.vue';
|
||||
import ToastModal from '@c/modal/ToastModal.vue';
|
||||
import { useLoadingStore } from "@s/loadingStore";
|
||||
import LoadingSpinner from "@v/LoadingPage.vue";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const route = useRoute();
|
||||
|
||||
const layout = computed(() => {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import axios from 'axios';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useToastStore } from '@s/toastStore';
|
||||
import { useLoadingStore } from "@s/loadingStore";
|
||||
|
||||
const $api = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
@ -14,6 +15,9 @@ const $api = axios.create({
|
||||
*/
|
||||
$api.interceptors.request.use(
|
||||
function (config) {
|
||||
const loadingStore = useLoadingStore();
|
||||
loadingStore.startLoading();
|
||||
|
||||
let contentType = 'application/json';
|
||||
|
||||
if (config.isFormData) contentType = 'multipart/form-data';
|
||||
@ -24,6 +28,8 @@ $api.interceptors.request.use(
|
||||
return config;
|
||||
},
|
||||
function (error) {
|
||||
const loadingStore = useLoadingStore();
|
||||
loadingStore.stopLoading();
|
||||
// 요청 오류가 있는 작업 수행
|
||||
return Promise.reject(error);
|
||||
},
|
||||
@ -32,10 +38,15 @@ $api.interceptors.request.use(
|
||||
// 응답 인터셉터 추가하기
|
||||
$api.interceptors.response.use(
|
||||
function (response) {
|
||||
const loadingStore = useLoadingStore();
|
||||
loadingStore.stopLoading();
|
||||
// 2xx 범위의 응답 처리
|
||||
return response;
|
||||
},
|
||||
function (error) {
|
||||
const loadingStore = useLoadingStore();
|
||||
loadingStore.stopLoading();
|
||||
|
||||
const toastStore = useToastStore();
|
||||
// 오류 응답 처리
|
||||
if (error.response) {
|
||||
|
||||
@ -63,8 +63,8 @@
|
||||
margin-left: 260px;
|
||||
width: auto !important;
|
||||
min-width: auto !important;
|
||||
right: 24px !important;
|
||||
left: 24px !important;
|
||||
right: 26px !important;
|
||||
left: 26px !important;
|
||||
}
|
||||
|
||||
/* 탑바 범위조정(1200px 이하) */
|
||||
@ -75,8 +75,8 @@
|
||||
margin-left: 0px;
|
||||
width: auto !important;
|
||||
min-width: auto !important;
|
||||
right: 24px !important;
|
||||
left: 24px !important;
|
||||
right: 26px !important;
|
||||
left: 26px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +88,8 @@
|
||||
margin-left: 0px;
|
||||
width: auto !important;
|
||||
min-width: auto !important;
|
||||
right: 24px !important;
|
||||
left: 24px !important;
|
||||
right: 26px !important;
|
||||
left: 26px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
24
src/stores/loadingStore.js
Normal file
24
src/stores/loadingStore.js
Normal file
@ -0,0 +1,24 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref, computed } from "vue";
|
||||
|
||||
export const useLoadingStore = defineStore("loading", () => {
|
||||
const loadingCount = ref(0); // 요청 개수를 추적
|
||||
|
||||
const startLoading = () => {
|
||||
loadingCount.value++;
|
||||
console.log(loadingCount.value)
|
||||
};
|
||||
|
||||
const stopLoading = () => {
|
||||
if (loadingCount.value > 0) {
|
||||
setTimeout(() => {
|
||||
loadingCount.value--;
|
||||
console.log("Stop Loading: ", loadingCount.value);
|
||||
}, 200); // 약간의 지연을 추가하여 응답이 동시에 도착해도 안정적으로 감소
|
||||
}
|
||||
};
|
||||
|
||||
const isLoading = computed(() => loadingCount.value > 0); // 하나라도 요청이 있으면 로딩 활성화
|
||||
|
||||
return { isLoading, startLoading, stopLoading };
|
||||
});
|
||||
@ -1,24 +1,45 @@
|
||||
<template>
|
||||
<div v-if="isLoading" class="loading-overlay">
|
||||
<div class="loading-container">
|
||||
<div class="spinner">
|
||||
🐰
|
||||
</div>
|
||||
<div class="spinner">🐰</div>
|
||||
<p class="loading-text">잠시만 기다려 주세요...</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from "vue";
|
||||
|
||||
defineProps({
|
||||
isLoading: Boolean, // 부모 컴포넌트에서 전달받는 로딩 상태
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 회색 배경으로 클릭 방지 */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.4); /* 회색 반투명 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999; /* 가장 위에 위치 */
|
||||
pointer-events: auto; /* 모든 클릭 방지 */
|
||||
}
|
||||
|
||||
/* 로딩 컨테이너 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background-color: #f9f9f9;
|
||||
padding: 20px;
|
||||
background: none;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* 빙글빙글 돌아가는 스피너 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user