refactor(theme): 优化文章列表翻页交互

This commit is contained in:
pengzhanbo 2022-05-07 14:50:28 +08:00
parent 19b1581281
commit 0f7734825d
6 changed files with 41 additions and 32 deletions

View File

@ -1,12 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { usePageFrontmatter } from '@vuepress/client'
import { debounce } from 'ts-debounce' import { debounce } from 'ts-debounce'
import { computed, onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { getScrollTop, scrollTo } from '../utils' import { getScrollTop, scrollTo } from '../utils'
import { BackTopIcon } from './icons' import { BackTopIcon } from './icons'
const frontmatter = usePageFrontmatter()
const opacity = ref<number>(0) const opacity = ref<number>(0)
const MAX_TOP = 300 const MAX_TOP = 300
@ -14,20 +11,8 @@ const canShow = debounce((): void => {
opacity.value = getScrollTop(document) >= MAX_TOP ? 1 : 0 opacity.value = getScrollTop(document) >= MAX_TOP ? 1 : 0
}) })
const top = computed(() => {
if (__VUEPRESS_SSR__) return 0
if (
frontmatter.value.home &&
(frontmatter.value.banner || frontmatter.value.mobileBanner)
) {
return document.documentElement.clientHeight - 58
} else {
return 0
}
})
const scrollToTop = (): void => { const scrollToTop = (): void => {
scrollTo(document, top.value) scrollTo(document, 0)
} }
onMounted(() => { onMounted(() => {

View File

@ -69,8 +69,6 @@ const useSocialList = (): SocialRef => {
const socialList = useSocialList() const socialList = useSocialList()
const postStat = usePostStat() const postStat = usePostStat()
console.log(postStat)
</script> </script>
<template> <template>
<DropdownTransition> <DropdownTransition>

View File

@ -2,10 +2,7 @@
import { usePageFrontmatter, withBase } from '@vuepress/client' import { usePageFrontmatter, withBase } from '@vuepress/client'
import { isLinkHttp } from '@vuepress/shared' import { isLinkHttp } from '@vuepress/shared'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import type { import type { PlumeThemeHomeFrontmatter } from '../../shared'
PlumeThemeHomeFrontmatter,
PlumeThemeLocaleOptions,
} from '../../shared'
import { useThemeLocaleData } from '../composables' import { useThemeLocaleData } from '../composables'
import { scrollTo } from '../utils' import { scrollTo } from '../utils'
import { ArrowBottomIcon } from './icons' import { ArrowBottomIcon } from './icons'

View File

@ -1,6 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useOffsetPagination } from '@vueuse/core' import { useOffsetPagination } from '@vueuse/core'
import { computed, ref, toRefs } from 'vue' import { computed, ref, toRefs } from 'vue'
import { ArrowDoubleLeftIcon, ArrowDoubleRightIcon } from './icons'
const emit = defineEmits(['togglePage']) const emit = defineEmits(['togglePage'])
const props = defineProps({ const props = defineProps({
@ -75,7 +76,7 @@ function handleJump(): void {
:disabled="isFirstPage" :disabled="isFirstPage"
@click="prev" @click="prev"
> >
prev <ArrowDoubleLeftIcon />
</button> </button>
<template v-for="count in pageList" :key="count"> <template v-for="count in pageList" :key="count">
<button <button
@ -94,7 +95,7 @@ function handleJump(): void {
:disabled="isLastPage" :disabled="isLastPage"
@click="next" @click="next"
> >
next <ArrowDoubleRightIcon />
</button> </button>
</div> </div>
<div class="pagination-form can-hide"> <div class="pagination-form can-hide">
@ -151,6 +152,15 @@ function handleJump(): void {
color: var(--c-text); color: var(--c-text);
} }
} }
&.btn-prev,
&.btn-next {
.icon {
width: 14px;
height: 14px;
vertical-align: text-top;
}
}
} }
.pagination-form { .pagination-form {

View File

@ -33,23 +33,23 @@ watch(
) )
const route = useRoute() const route = useRoute()
let offsetHeight = 0
onBeforeRouteUpdate((to) => { onBeforeRouteUpdate((to) => {
if (__VUEPRESS_SSR__) return if (__VUEPRESS_SSR__) return
setPostListPage((to.query.p as unknown as number) || 1) setPostListPage((to.query.p as unknown as number) || 1)
const { home, banner, mobileBanner } = frontmatter.value const { home, banner, mobileBanner } = frontmatter.value
let top = 0 let top = 0
if (home && (banner || mobileBanner)) { if (home && (banner || mobileBanner)) {
rect = offsetHeight =
rect || document.querySelector('.navbar-wrapper')?.getBoundingClientRect() offsetHeight ||
top = document.documentElement.clientHeight - (rect?.height || 0) document.querySelector<HTMLElement>('.navbar-wrapper')?.offsetHeight ||
0
top = document.documentElement.clientHeight - offsetHeight
} }
scrollTo(document, top) setTimeout(() => scrollTo(document, top), 0)
}) })
setPostListPage((route.query.p as unknown as number) || 1) setPostListPage((route.query.p as unknown as number) || 1)
let rect: any
const togglePage = (currentPage: number): void => { const togglePage = (currentPage: number): void => {
router.push({ router.push({
path: route.path, path: route.path,

View File

@ -88,3 +88,22 @@ export const PostIcon: FunctionalComponent = () =>
}) })
) )
PostIcon.displayName = 'PostIcon' PostIcon.displayName = 'PostIcon'
export const ArrowDoubleRightIcon: FunctionalComponent = () =>
h(IconBase, { name: 'arrow-double-right', viewBox: '0 0 1024 1024' }, () =>
h('path', {
d: 'M160.117 212.026v-82.233a8 8 0 0 1 13.33-5.966l407.697 364.298c0.9 0.804 1.753 1.658 2.556 2.558 11.764 13.186 10.62 33.419-2.556 45.192L173.448 900.173a8 8 0 0 1-13.33-5.966v-82.233a16 16 0 0 1 5.338-11.93L487.814 512 165.456 223.957a16 16 0 0 1-5.339-11.931z m272.057 0v-82.233a8 8 0 0 1 13.33-5.966l407.697 364.298c0.9 0.804 1.753 1.658 2.556 2.558 11.764 13.186 10.62 33.419-2.556 45.192L445.505 900.173a8 8 0 0 1-13.33-5.966v-82.233a16 16 0 0 1 5.339-11.93L759.87 512 437.514 223.957a16 16 0 0 1-5.34-11.931z',
})
)
ArrowDoubleRightIcon.displayName = 'ArrowDoubleRightIcon'
export const ArrowDoubleLeftIcon: FunctionalComponent = () =>
h(IconBase, { name: 'arrow-double-left', viewBox: '0 0 1024 1024' }, () => [
h('path', {
d: 'M495.976 476.195c19.777 17.656 21.494 48 3.837 67.774a48.003 48.003 0 0 1-3.837 3.836L536.082 512l-40.106-35.805zM864 212.083v-82.217a8 8 0 0 0-13.328-5.967L442.69 488.13c-0.9 0.804-1.754 1.657-2.558 2.557-11.772 13.184-10.626 33.412 2.558 45.183l407.983 364.231A8 8 0 0 0 864 894.134v-82.217a16 16 0 0 0-5.344-11.936L536.082 512l322.574-287.981A16 16 0 0 0 864 212.083zM495.976 476.195c19.777 17.656 21.494 48 3.837 67.774a48.003 48.003 0 0 1-3.837 3.836L536.082 512l-40.106-35.805zM864 212.083v-82.217a8 8 0 0 0-13.328-5.967L442.69 488.13c-0.9 0.804-1.754 1.657-2.558 2.557-11.772 13.184-10.626 33.412 2.558 45.183l407.983 364.231A8 8 0 0 0 864 894.134v-82.217a16 16 0 0 0-5.344-11.936L536.082 512l322.574-287.981A16 16 0 0 0 864 212.083z',
}),
h('path', {
d: 'M223.976 476.195c19.777 17.656 21.494 48 3.837 67.774a48.003 48.003 0 0 1-3.837 3.836L264.082 512l-40.106-35.805zM592 212.083v-82.217a8 8 0 0 0-13.328-5.967L170.69 488.13c-0.9 0.804-1.754 1.657-2.558 2.557-11.772 13.184-10.626 33.412 2.558 45.183l407.983 364.231A8 8 0 0 0 592 894.134v-82.217a16 16 0 0 0-5.344-11.936L264.082 512l322.574-287.981A16 16 0 0 0 592 212.083zM223.976 476.195c19.777 17.656 21.494 48 3.837 67.774a48.003 48.003 0 0 1-3.837 3.836L264.082 512l-40.106-35.805zM592 212.083v-82.217a8 8 0 0 0-13.328-5.967L170.69 488.13c-0.9 0.804-1.754 1.657-2.558 2.557-11.772 13.184-10.626 33.412 2.558 45.183l407.983 364.231A8 8 0 0 0 592 894.134v-82.217a16 16 0 0 0-5.344-11.936L264.082 512l322.574-287.981A16 16 0 0 0 592 212.083z',
}),
])
ArrowDoubleLeftIcon.displayName = 'ArrowDoubleLeftIcon'