feat: 文章列表页分页路由映射

This commit is contained in:
pengzhanbo 2024-01-07 01:50:04 +08:00
parent 36aa6c99b5
commit 12917050c8
2 changed files with 149 additions and 10 deletions

View File

@ -1,8 +1,8 @@
import { usePageLang } from '@vuepress/client'
import { useBlogPostData } from '@vuepress-plume/plugin-blog-data/client'
import { computed, ref } from 'vue'
import { computed } from 'vue'
import type { PlumeThemeBlogPostItem } from '../../shared/index.js'
import { useLocaleLink, useThemeLocaleData } from '../composables/index.js'
import { useLocaleLink, useRouteQuery, useThemeLocaleData } from '../composables/index.js'
import { getRandomColor, toArray } from '../utils/index.js'
export function useLocalePostList() {
@ -33,10 +33,18 @@ export function usePostListControl() {
return next.sticky > prev.sticky ? 1 : -1
}),
...otherList,
]
] as PlumeThemeBlogPostItem[]
})
const page = ref(1)
const page = useRouteQuery('p', 1, {
mode: 'push',
transform(val) {
const page = Number(val)
if (!Number.isNaN(page) && page > 0)
return page
return 1
},
})
const totalPage = computed(() => {
if (blog.value.pagination === false)
@ -133,14 +141,15 @@ export function useTags() {
}))
})
const postList = ref<ShortPostItem[]>([])
const currentTag = ref<string>()
const currentTag = useRouteQuery<string>('tag')
const handleTagClick = (tag: string) => {
currentTag.value = tag
postList.value = list.value.filter((item) => {
const postList = computed<ShortPostItem[]>(() => {
if (!currentTag.value)
return []
return list.value.filter((item) => {
if (item.tags)
return toArray(item.tags).includes(tag)
return toArray(item.tags).includes(currentTag.value)
return false
}).map(item => ({
@ -148,6 +157,10 @@ export function useTags() {
path: item.path,
createTime: item.createTime.split(' ')[0].replace(/\//g, '-'),
}))
})
const handleTagClick = (tag: string) => {
currentTag.value = tag
}
return {

View File

@ -0,0 +1,126 @@
import { customRef, nextTick, toValue, watch } from 'vue'
import type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { RouteParamValueRaw, Router } from 'vue-router'
import { tryOnScopeDispose } from '@vueuse/core'
export type RouteQueryValueRaw = RouteParamValueRaw | string[]
export interface ReactiveRouteOptions {
/**
* Mode to update the router query, ref is also acceptable
*
* @default 'replace'
*/
mode?: MaybeRef<'replace' | 'push'>
/**
* Route instance, use `useRoute()` if not given
*/
route?: ReturnType<typeof useRoute>
/**
* Router instance, use `useRouter()` if not given
*/
router?: ReturnType<typeof useRouter>
}
export interface ReactiveRouteOptionsWithTransform<V, R> extends ReactiveRouteOptions {
/**
* Function to transform data before return
*/
transform?: (val: V) => R
}
const _queue = new WeakMap<Router, Map<string, any>>()
export function useRouteQuery(
name: string
): Ref<null | string | string[]>
export function useRouteQuery<
T extends RouteQueryValueRaw = RouteQueryValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options?: ReactiveRouteOptionsWithTransform<T, K>
): Ref<K>
export function useRouteQuery<
T extends RouteQueryValueRaw = RouteQueryValueRaw,
K = T,
>(
name: string,
defaultValue?: MaybeRefOrGetter<T>,
options: ReactiveRouteOptionsWithTransform<T, K> = {},
): Ref<K> {
const {
mode = 'replace',
route = useRoute(),
router = useRouter(),
transform = value => value as any as K,
} = options
if (!_queue.has(router))
_queue.set(router, new Map())
const _queriesQueue = _queue.get(router)!
let query = route.query[name] as any
tryOnScopeDispose(() => {
query = undefined
})
let _trigger: () => void
const proxy = customRef<any>((track, trigger) => {
_trigger = trigger
return {
get() {
track()
return transform(query !== undefined ? query : toValue(defaultValue))
},
set(v) {
if (query === v)
return
query = v
_queriesQueue.set(name, v)
trigger()
nextTick(() => {
if (_queriesQueue.size === 0)
return
const newQueries = Object.fromEntries(_queriesQueue.entries())
_queriesQueue.clear()
const { params, query, hash } = route
router[toValue(mode)]({
params,
query: { ...query, ...newQueries },
hash,
})
})
},
}
})
watch(
() => route.query[name],
(v) => {
query = v
_trigger()
},
{ flush: 'sync' },
)
return proxy as any as Ref<K>
}