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: {}
|
default: {}
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const nuxtApp = useNuxtApp()
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const allowScrollTop = ref(false)
|
const allowScrollTop = ref(false)
|
||||||
|
|
||||||
const restoreClickHook = () => {
|
usePageTransition({
|
||||||
if (isHydrated.value) {
|
beforeEach: () => {
|
||||||
|
allowScrollTop.value = false
|
||||||
|
},
|
||||||
|
afterHydrated: () => {
|
||||||
if (typeof props.to === 'string')
|
if (typeof props.to === 'string')
|
||||||
allowScrollTop.value = router.currentRoute.value.fullPath === props.to
|
allowScrollTop.value = router.currentRoute.value.fullPath === props.to
|
||||||
else
|
else
|
||||||
allowScrollTop.value = router.currentRoute.value.name === props.to.name
|
allowScrollTop.value = router.currentRoute.value.name === props.to.name
|
||||||
}
|
},
|
||||||
}
|
onTransitionError: () => {
|
||||||
|
|
||||||
router.afterEach(() => {
|
|
||||||
allowScrollTop.value = false
|
allowScrollTop.value = false
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
nuxtApp.hooks.hook('app:suspense:resolve', restoreClickHook)
|
|
||||||
nuxtApp.hooks.hook('page:finish', restoreClickHook)
|
|
||||||
|
|
||||||
useCommand({
|
useCommand({
|
||||||
scope: 'Navigation',
|
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) => {
|
export default defineNuxtPlugin(() => {
|
||||||
const router = useRouter()
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const track = ref(false)
|
const track = ref(false)
|
||||||
const { y } = useWindowScroll()
|
const { y } = useWindowScroll()
|
||||||
const storage = useLocalStorage<Record<string, number>>('elk-track-scroll', {})
|
const storage = useLocalStorage<Record<string, number>>('elk-track-scroll', {})
|
||||||
const customRoutes = new Set<string>()
|
const customRoutes = new Set<string>()
|
||||||
|
|
||||||
router.beforeEach(async () => {
|
|
||||||
track.value = false
|
|
||||||
})
|
|
||||||
router.onError(async () => {
|
|
||||||
track.value = true
|
|
||||||
})
|
|
||||||
|
|
||||||
const forceScrollToTop = () => {
|
const forceScrollToTop = () => {
|
||||||
storage.value[route.fullPath] = 0
|
storage.value[route.fullPath] = 0
|
||||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||||
|
@ -60,18 +52,21 @@ export default defineNuxtPlugin((nuxtApp) => {
|
||||||
|
|
||||||
const restoreScroll = () => restoreScrollCallback(false)
|
const restoreScroll = () => restoreScrollCallback(false)
|
||||||
|
|
||||||
const restoreScrollHook = () => {
|
const restoreCustomPageScroll = () => restoreScrollCallback(true)
|
||||||
if (isHydrated.value) {
|
|
||||||
|
usePageTransition({
|
||||||
|
beforeEach: () => {
|
||||||
|
track.value = false
|
||||||
|
},
|
||||||
|
afterHydrated: () => {
|
||||||
restoreScroll().then(() => {
|
restoreScroll().then(() => {
|
||||||
track.value = true
|
track.value = true
|
||||||
}).catch(noop)
|
}).catch(noop)
|
||||||
}
|
},
|
||||||
}
|
onTransitionError: () => {
|
||||||
|
track.value = true
|
||||||
const restoreCustomPageScroll = () => restoreScrollCallback(true)
|
},
|
||||||
|
})
|
||||||
nuxtApp.hooks.hook('app:suspense:resolve', restoreScrollHook)
|
|
||||||
nuxtApp.hooks.hook('page:finish', restoreScrollHook)
|
|
||||||
|
|
||||||
watch([track, y, () => route], ([trackEnabled, scrollPosition, r]) => {
|
watch([track, y, () => route], ([trackEnabled, scrollPosition, r]) => {
|
||||||
if (trackEnabled && (!r.meta || !r.meta?.noScrollTrack))
|
if (trackEnabled && (!r.meta || !r.meta?.noScrollTrack))
|
||||||
|
|
Loading…
Reference in a new issue