forked from Mirrors/elk
chore: create page-transition composable
This commit is contained in:
parent
6dde98eb78
commit
a64c0f4e9b
3 changed files with 51 additions and 29 deletions
|
@ -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',
|
||||
|
||||
|
|
29
composables/page-transiton.ts
Normal file
29
composables/page-transiton.ts
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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<Record<string, number>>('elk-track-scroll', {})
|
||||
const customRoutes = new Set<string>()
|
||||
|
||||
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))
|
||||
|
|
Loading…
Reference in a new issue