localhost-front/src/components/button/ScrollTopButton.vue
2025-04-04 17:06:42 +09:00

88 lines
2.3 KiB
Vue

<template>
<!-- 뒤로가기 -->
<button
v-if="canGoBack"
@click="goBack"
:disabled="!canGoBack"
:class="{ 'shifted': showButton }"
class="back-btn rounded-pill btn-icon btn-secondary position-fixed shadow z-5 border-0">
<i class='bx bx-chevron-left'></i>
</button>
<!-- 위로 -->
<button
@click="scrollToTop"
class="scroll-top-btn rounded-pill btn-icon btn-primary position-fixed shadow z-5 border-0"
:class="{ 'visible': showButton, 'hidden': !showButton }"
>
<i class='bx bx-chevron-up'></i>
</button>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
const showButton = ref(false);
const canGoBack = ref(false);
const route = useRoute();
const router = useRouter();
const loginPagePath = "/login"; // 로그인 페이지 기본 경로
// 스크롤 이벤트 핸들러
const handleScroll = () => {
showButton.value = window.scrollY > 200;
};
// 최상단으로 스크롤 이동
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: "smooth" });
};
// 뒤로 가기 처리
const goBack = () => {
if (canGoBack.value) {
router.back();
}
};
// 뒤로 가기 가능 여부 확인 함수
const updateCanGoBack = () => {
const historyBack = router.options.history.state.back;
const previousPage = document.referrer;
// URL에서 경로만 추출하는 함수
const getPath = (url) => {
try {
return new URL(url, window.location.origin).pathname; // 쿼리 제거
} catch {
return ""; // 잘못된 URL 처리
}
};
const previousPath = getPath(previousPage);
// 뒤로 갈 수 있는 조건:
canGoBack.value = !!historyBack
&& getPath(historyBack) !== loginPagePath
&& !previousPath.startsWith(loginPagePath);
};
// 마운트 시 한 번 실행
onMounted(() => {
window.addEventListener("scroll", handleScroll);
updateCanGoBack();
});
// 라우트가 변경될 때마다 `canGoBack` 업데이트
watch(route, () => {
updateCanGoBack();
});
// 언마운트 시 이벤트 제거
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll);
});
</script>