From 4c8f6e44f6689c95e432b0ce3c2da04dfe123ba8 Mon Sep 17 00:00:00 2001 From: zenn Date: Mon, 6 Jul 2026 14:28:24 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EA=B9=9C=EB=B9=A1=EC=9E=84=20=EC=99=84=ED=99=94=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20(v1.10.50)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 게시물 상세를 default 레이아웃으로 통합해 홈↔게시물 레이아웃 교체 제거 - CSS 전환 베일·스크롤 정리 플러그인으로 이동 중 깜빡임 완화 Co-authored-by: Cursor --- app.vue | 92 ++------------- app/router.options.js | 25 ++++ assets/css/main.css | 18 +++ docs/spec.md | 2 +- docs/update.md | 14 +++ lib/site-route-transition.js | 65 ++++++++++ package.json | 2 +- pages/post/[slug].vue | 2 +- plugins/site-page-transition.client.js | 157 +++++++++++++++++++++++++ 9 files changed, 293 insertions(+), 84 deletions(-) create mode 100644 app/router.options.js create mode 100644 lib/site-route-transition.js create mode 100644 plugins/site-page-transition.client.js diff --git a/app.vue b/app.vue index cbc7ae5..562ec73 100644 --- a/app.vue +++ b/app.vue @@ -18,68 +18,7 @@ const siteAccentStyle = computed(() => ({ '--site-accent': siteAccentColor.value })) -const isSitePageNavigating = ref(false) - -if (import.meta.client) { - const nuxtApp = useNuxtApp() - const router = useRouter() - - /** @type {ReturnType | null} */ - let hideOverlayTimer = null - let navigationOverlayToken = 0 - - /** - * 공개 페이지 이동 로딩 오버레이를 표시한다. - * @returns {void} - */ - const showSitePageNavigationOverlay = () => { - navigationOverlayToken += 1 - clearTimeout(hideOverlayTimer) - hideOverlayTimer = null - isSitePageNavigating.value = true - } - - /** - * 새 화면이 실제로 그려진 뒤 공개 페이지 이동 로딩 오버레이를 숨긴다. - * @returns {void} - */ - const scheduleHideSitePageNavigationOverlay = () => { - const token = navigationOverlayToken - - requestAnimationFrame(() => { - requestAnimationFrame(() => { - hideOverlayTimer = setTimeout(() => { - if (token !== navigationOverlayToken) { - return - } - - isSitePageNavigating.value = false - hideOverlayTimer = null - }, 120) - }) - }) - } - - /** - * 오류·취소 상황에서 공개 페이지 이동 로딩 오버레이를 즉시 숨긴다. - * @returns {void} - */ - const hideSitePageNavigationOverlayImmediately = () => { - clearTimeout(hideOverlayTimer) - hideOverlayTimer = null - isSitePageNavigating.value = false - } - - router.beforeEach((to, from) => { - if (to.fullPath !== from.fullPath) { - showSitePageNavigationOverlay() - } - }) - router.onError(hideSitePageNavigationOverlayImmediately) - nuxtApp.hook('page:loading:start', showSitePageNavigationOverlay) - nuxtApp.hook('page:finish', scheduleHideSitePageNavigationOverlay) - nuxtApp.hook('app:error', hideSitePageNavigationOverlayImmediately) -} +const isSitePageNavigating = useState('site-page-veil', () => false) useHead(() => ({ titleTemplate: (titleChunk) => titleChunk || appSiteSettings.value.title, @@ -97,27 +36,18 @@ useHead(() => ({