From a64c0f4e9b5efafcd29fc1a8ace2bdd3ed136bf6 Mon Sep 17 00:00:00 2001 From: userquin Date: Sat, 11 Feb 2023 16:20:12 +0100 Subject: [PATCH] chore: create page-transition composable --- components/nav/NavSideItem.vue | 20 +++++++--------- composables/page-transiton.ts | 29 +++++++++++++++++++++++ plugins/track-scroll-position.client.ts | 31 +++++++++++-------------- 3 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 composables/page-transiton.ts diff --git a/components/nav/NavSideItem.vue b/components/nav/NavSideItem.vue index 317e9497..008d2633 100644 --- a/components/nav/NavSideItem.vue +++ b/components/nav/NavSideItem.vue @@ -14,27 +14,25 @@ defineSlots<{ default: {} }>() -const nuxtApp = useNuxtApp() const router = useRouter() const allowScrollTop = ref(false) -const restoreClickHook = () => { - if (isHydrated.value) { +usePageTransition({ + beforeEach: () => { + allowScrollTop.value = false + }, + afterHydrated: () => { if (typeof props.to === 'string') allowScrollTop.value = router.currentRoute.value.fullPath === props.to else allowScrollTop.value = router.currentRoute.value.name === props.to.name - } -} - -router.afterEach(() => { - allowScrollTop.value = false + }, + onTransitionError: () => { + allowScrollTop.value = false + }, }) -nuxtApp.hooks.hook('app:suspense:resolve', restoreClickHook) -nuxtApp.hooks.hook('page:finish', restoreClickHook) - useCommand({ scope: 'Navigation', diff --git a/composables/page-transiton.ts b/composables/page-transiton.ts new file mode 100644 index 00000000..f8d34228 --- /dev/null +++ b/composables/page-transiton.ts @@ -0,0 +1,29 @@ +export const usePageTransition = (options: { + beforeEach?: typeof noop + afterHydrated?: typeof noop + onTransitionError?: typeof noop +}) => { + const nuxtApp = useNuxtApp() + const router = useRouter() + + if (options.beforeEach) { + router.beforeEach(() => { + options.beforeEach?.() + }) + } + + if (options.onTransitionError) { + router.onError(() => { + options.onTransitionError?.() + }) + } + + if (options.afterHydrated) { + const nuxtHook = () => { + if (isHydrated.value) + options.afterHydrated?.() + } + nuxtApp.hooks.hook('app:suspense:resolve', nuxtHook) + nuxtApp.hooks.hook('page:finish', nuxtHook) + } +} diff --git a/plugins/track-scroll-position.client.ts b/plugins/track-scroll-position.client.ts index 41abbee1..6adc3ae4 100644 --- a/plugins/track-scroll-position.client.ts +++ b/plugins/track-scroll-position.client.ts @@ -1,18 +1,10 @@ -export default defineNuxtPlugin((nuxtApp) => { - const router = useRouter() +export default defineNuxtPlugin(() => { const route = useRoute() const track = ref(false) const { y } = useWindowScroll() const storage = useLocalStorage>('elk-track-scroll', {}) const customRoutes = new Set() - router.beforeEach(async () => { - track.value = false - }) - router.onError(async () => { - track.value = true - }) - const forceScrollToTop = () => { storage.value[route.fullPath] = 0 window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }) @@ -60,18 +52,21 @@ export default defineNuxtPlugin((nuxtApp) => { const restoreScroll = () => restoreScrollCallback(false) - const restoreScrollHook = () => { - if (isHydrated.value) { + const restoreCustomPageScroll = () => restoreScrollCallback(true) + + usePageTransition({ + beforeEach: () => { + track.value = false + }, + afterHydrated: () => { restoreScroll().then(() => { track.value = true }).catch(noop) - } - } - - const restoreCustomPageScroll = () => restoreScrollCallback(true) - - nuxtApp.hooks.hook('app:suspense:resolve', restoreScrollHook) - nuxtApp.hooks.hook('page:finish', restoreScrollHook) + }, + onTransitionError: () => { + track.value = true + }, + }) watch([track, y, () => route], ([trackEnabled, scrollPosition, r]) => { if (trackEnabled && (!r.meta || !r.meta?.noScrollTrack))