mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
This commit is contained in:
parent
c32dd3eb93
commit
c6907dfe74
@ -96,18 +96,47 @@ interface BlogOptions {
|
||||
* @default true
|
||||
*/
|
||||
tags?: boolean
|
||||
|
||||
/**
|
||||
* 自定义标签页链接
|
||||
*
|
||||
* @default '/blog/tags/'
|
||||
*/
|
||||
tagsLink?: string
|
||||
|
||||
/**
|
||||
* 是否启用归档页
|
||||
* @default true
|
||||
*/
|
||||
archives?: boolean
|
||||
|
||||
/**
|
||||
* 自定义归档页链接
|
||||
*
|
||||
* @default '/blog/archives/'
|
||||
*/
|
||||
archivesLink?: string
|
||||
|
||||
/**
|
||||
* 是否启用分类页
|
||||
* @default true
|
||||
*/
|
||||
categories?: boolean
|
||||
|
||||
/**
|
||||
* 自定义分类页链接
|
||||
*
|
||||
* @default '/blog/categories/'
|
||||
*/
|
||||
categoriesLink?: string
|
||||
|
||||
/**
|
||||
* 分类页展开深度
|
||||
*
|
||||
* @default 'deep'
|
||||
*/
|
||||
categoriesExpand?: number | 'deep'
|
||||
|
||||
/**
|
||||
* 博客文章封面图
|
||||
*
|
||||
|
||||
@ -18,7 +18,7 @@ const { categories } = useBlogCategory()
|
||||
<slot name="blog-categories-content-before" />
|
||||
|
||||
<div class="content">
|
||||
<VPCategories :items="categories" />
|
||||
<VPCategories :items="categories" :depth="0" />
|
||||
</div>
|
||||
|
||||
<slot name="blog-categories-after" />
|
||||
|
||||
@ -3,9 +3,12 @@ import type { BlogCategoryItem, BlogCategoryItemWithPost } from '../../composabl
|
||||
import VPCategoriesGroup from '@theme/Blog/VPCategoriesGroup.vue'
|
||||
import VPLink from '@theme/VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
withDefaults(defineProps<{
|
||||
items: (BlogCategoryItem | BlogCategoryItemWithPost)[]
|
||||
}>()
|
||||
depth?: number
|
||||
}>(), {
|
||||
depth: 0,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -19,7 +22,7 @@ defineProps<{
|
||||
<span class="vpi-post" />
|
||||
<VPLink :href="item.path" :text="item.title" />
|
||||
</p>
|
||||
<VPCategoriesGroup v-else :item="item" />
|
||||
<VPCategoriesGroup v-else :item="item" :depth="depth + 1" />
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
@ -1,53 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import type { BlogCategoryItem } from '../../composables/index.js'
|
||||
import VPCategories from '@theme/Blog/VPCategories.vue'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vuepress/client'
|
||||
import { useData } from '../../composables/index.js'
|
||||
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
item: BlogCategoryItem
|
||||
}>()
|
||||
|
||||
depth?: number
|
||||
}>(), {
|
||||
depth: 0,
|
||||
})
|
||||
const { theme } = useData()
|
||||
const route = useRoute()
|
||||
const el = ref<HTMLDivElement | null>(null)
|
||||
const active = ref(true)
|
||||
const isActive = ref(false)
|
||||
const expand = ref(true)
|
||||
const isExpand = ref(false)
|
||||
|
||||
const expandDepth = computed(() => {
|
||||
const blog = typeof theme.value.blog === 'boolean' ? {} : theme.value.blog
|
||||
const depth = blog?.categoriesExpand ?? 'deep'
|
||||
if (depth === 'deep')
|
||||
return Infinity
|
||||
const d = Number(depth)
|
||||
if (Number.isNaN(d))
|
||||
return Infinity
|
||||
return d
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [route.query, props.item],
|
||||
() => [route.query, props.item, expandDepth.value],
|
||||
() => {
|
||||
const id = route.query.id as string
|
||||
if (!id) {
|
||||
active.value = true
|
||||
expand.value = props.depth <= expandDepth.value
|
||||
}
|
||||
else {
|
||||
active.value = hasActive(props.item, id)
|
||||
expand.value = hasExpand(props.item, id)
|
||||
}
|
||||
isActive.value = id ? props.item.id === id : false
|
||||
isExpand.value = id ? props.item.id === id : false
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
function hasActive(item: BlogCategoryItem, id: string) {
|
||||
function hasExpand(item: BlogCategoryItem, id: string) {
|
||||
return item.id === id
|
||||
|| item.items.filter(item => item.type === 'category').some(item => hasActive(item, id))
|
||||
|| item.items.filter(item => item.type === 'category').some(item => hasExpand(item, id))
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
active.value = !active.value
|
||||
expand.value = !expand.value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (el.value && isActive.value) {
|
||||
if (el.value && isExpand.value) {
|
||||
el.value.scrollIntoView({ block: 'center' })
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="el" class="vp-category-group" :class="{ active }">
|
||||
<div ref="el" class="vp-category-group" :class="{ expand }">
|
||||
<p class="folder" @click="toggle">
|
||||
<span class="icon" :class="[active ? 'vpi-folder-open' : 'vpi-folder']" />
|
||||
<span class="icon" :class="[expand ? 'vpi-folder-open' : 'vpi-folder']" />
|
||||
<span>{{ item.title }}</span>
|
||||
</p>
|
||||
|
||||
@ -55,6 +70,7 @@ onMounted(() => {
|
||||
v-if="item.items.length"
|
||||
class="group"
|
||||
:items="item.items"
|
||||
:depth="depth"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -113,7 +129,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.vp-category-group.active > .group {
|
||||
.vp-category-group.expand > .group {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -64,6 +64,12 @@ function sortCategory(items: BlogCategory): BlogCategory {
|
||||
if (a.type === 'category' && b.type === 'category') {
|
||||
return a.sort < b.sort ? -1 : 1
|
||||
}
|
||||
if (a.type === 'category' && b.type === 'post') {
|
||||
return -1
|
||||
}
|
||||
if (a.type === 'post' && b.type === 'category') {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
}
|
||||
|
||||
@ -100,6 +100,13 @@ export interface PlumeThemeBlog {
|
||||
*/
|
||||
categoriesLink?: string
|
||||
|
||||
/**
|
||||
* 分类页展开深度
|
||||
*
|
||||
* @default 'deep'
|
||||
*/
|
||||
categoriesExpand?: number | 'deep'
|
||||
|
||||
/**
|
||||
* 博客文章封面图
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user